git, nagios i hooks, zepsute repozytorium git

14

tło

Używamy nagios do monitorowania naszej infrastruktury. Obecnie nie mamy konfiguracji nagios pod kontrolą wersji i jest dwóch z nas, którzy zarządzają konfiguracją nagios. W związku z tym pracuję nad tym, aby przekształcić naszą konfigurację nagios w centralne repozytorium git, używając haków do sprawdzania składni, a następnie, jeśli konfiguracje wyglądają dobrze, uczyń je „aktywnymi”. Używam tego faceta jako punktu wyjścia.

Ogólny przepływ pracy, który próbuję wdrożyć, to:

  1. Edytuj lokalne repozytorium git konfiguracji nagios. Dodaj edytowane pliki, zatwierdzaj lokalnie.
  2. git push origin master do zdalnego repozytorium.
  3. Push jest przechwytywany przez przechwytywanie wstępne, które pobiera pliki, przenosi je do katalogu tymczasowego na serwerze i uruchamia je przez moduł sprawdzania składni nagios.
  4. Jeśli moduł sprawdzania składni przejdzie pomyślnie, zaakceptuj wypychanie, a następnie użyj haka po zatwierdzeniu git pullnowego kodu do katalogu konfiguracji nagios na żywo, a następnie ponownie uruchom nagios.
  5. Jeśli sprawdzanie składni nie powiedzie się, odrzuć wypychanie, pokazując użytkownikowi błąd składni nagios.

Napotykam jednak dziwne zachowanie, gdy odrzucam polecenie git push z powodu błędów składniowych w konfiguracji nagios. Oczekuję, że jeśli odrzuci hak, próba wypchnięcia powinna pozostawić repozytorium bez zmian. Ale tak się nie wydaje. Poniżej znajdują się szczegóły tego, co widzę:

Problem

Lokalnie edytuję konfigurację nagios, celowo włączając błąd składniowy, dodaję, a następnie zatwierdzam lokalnie:

host:nagios erik$ vi nagios.cfg
host:nagios erik$ git add nagios.cfg
host:nagios erik$ git commit -m "syntax error"
[master da71aed] syntax error
 1 files changed, 1 insertions(+), 0 deletions(-)

Teraz przekazuję te zmiany do głównego repozytorium. Zostanie to odrzucone z powodu błędu składniowego:

host:nagios erik$ git push origin master
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 12.74 KiB, done.
Total 3 (delta 1), reused 2 (delta 1)
remote: Previous HEAD position was 3ddc880... removed syntax error
remote: HEAD is now at da71aed... syntax error
remote: Nagios Config Check Exit Status: 254
remote: Your configs did not parse correctly, there was an error. Output follows.
remote:
remote: Nagios Core 3.2.3
remote: Copyright (c) 2009-2010 Nagios Core Development Team and Community Contributors
remote: Copyright (c) 1999-2009 Ethan Galstad
remote: Last Modified: 10-03-2010
remote: License: GPL
remote:
remote: Website: http://www.nagios.org
remote: Reading configuration data...
remote: Error in configuration file '/tmp/nagiosworkdir/nagios.cfg' - Line 23 (NULL value)
remote:    Error processing main config file!
remote:
remote:
remote:
remote: ***> One or more problems was encountered while processing the config files...
remote:
remote:      Check your configuration file(s) to ensure that they contain valid
remote:      directives and data defintions.  If you are upgrading from a previous
remote:      version of Nagios, you should be aware that some variables/definitions
remote:      may have been removed or modified in this version.  Make sure to read
remote:      the HTML documentation regarding the config files, as well as the
remote:      'Whats New' section to find out what has changed.
remote:
To [email protected]:nagios
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to '[email protected]:nagios'

To nie powinno było dotknąć zdalnego repozytorium, ale tak się stało. Jeśli przejdę do innego lokalnego katalogu tymczasowego i spróbuję sklonować repozytorium, otrzymam:

host:temp erik$ git clone [email protected]:nagios
Cloning into nagios...
remote: Counting objects: 30, done.
remote: Compressing objects: 100% (29/29), done.
remote: Total 30 (delta 12), reused 0 (delta 0)
Receiving objects: 100% (30/30), 29.81 KiB, done.
Resolving deltas: 100% (12/12), done.
error: Trying to write ref HEAD with nonexistant object da71aedfde2e0469288acd9e45bb8b57a6e5a7b3
fatal: Cannot update the ref 'HEAD'.

Teraz wracam do oryginalnego katalogu roboczego, naprawiam błąd składniowy, dodaję, zatwierdzam i wypycham:

host:nagios erik$ vi nagios.cfg
host:nagios erik$ git add nagios.cfg
host:nagios erik$ git commit -m "removing syntax error, push should succeed this time"
[master f147ded] removing syntax error, push should succeed this time
 1 files changed, 0 insertions(+), 2 deletions(-)
host:nagios erik$ git push origin master
Counting objects: 6, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 487 bytes, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: Previous HEAD position was 4c80d45... syntax error
remote: HEAD is now at f147ded... removing syntax error, push should succeed this time
remote: Nagios Config Check Exit Status: 0
remote: Your configs look good and parsed correctly.
To [email protected]:nagios
   3ddc880..f147ded  master -> master

W tym momencie repozytorium jest w porządku i mogę przejść do katalogu tymczasowego i ponownie sklonować repozytorium:

host:temp erik$ git clone [email protected]:nagios
Cloning into nagios...
remote: Counting objects: 34, done.
remote: Compressing objects: 100% (33/33), done.
remote: Total 34 (delta 14), reused 0 (delta 0)
Receiving objects: 100% (34/34), 30.22 KiB, done.
Resolving deltas: 100% (14/14), done.

Oto używany przeze mnie hak odbioru wstępnego .

Korzystam z git v1.7.5.4 na kliencie i v1.7.2.3 na serwerze.

Tak więc na pytanie : dlaczego repozytorium pozostaje w niespójnym stanie, gdy odrzucam push? Czy coś jest nie tak z moim haczykiem, czy może brakuje mi zrozumienia git?

EEAA
źródło
Jakiej wersji git używasz?
robbyt
@robbyt - 1.7.5.4na kliencie, 1.7.2.3na serwerze.
EEAA

Odpowiedzi:

7

Robisz:

export GIT_WORK_TREE=/tmp/nagiosworkdir
/usr/bin/git checkout -f $NEW_SHA1

w twoim haczyku. Mimo to nie dotyka zwykłych kopii roboczej to jest aktualizacją odniesień w git-dir (konkretnie HEADodniesienia), jak pokazano w błąd:

...
remote: HEAD is now at da71aed... syntax error
...

Twój haczyk próbuje exit 1odrzucić aktualizację, ale nie resetuje HEADreferencji po awarii.

Myślę, że musisz zaktualizować gałąź awarii w haku w następujący sposób:

...
if [ "$NAGIOS_CHECK_STATUS" -ne 0 ]
   then
   echo "Your configs did not parse correctly, there was an error. Output follows."
   cat $GIT_WORK_TREE/check.out
   /usr/bin/git reset --hard $OLD_SHA1    # <-- Add This
   exit 1
else
   ...
nickgrim
źródło
Wygląda świetnie, pseudonimie. Spróbuję dzisiaj trochę później. Dziękuję Ci!
EEAA
0

git checkoutPolecenie haka jest tworzenie / aktualizowanie ref HEAD w repozytorium.

Jeśli twoje repozytorium jest nagim repozytorium, może żyć bez referencji HEAD (nowe klony domyślnie sprawdzają swoją gałąź master , jeśli ją posiada); po prostu usuń odniesienie HEAD przed wyjściem (być może w taki trapsposób, abyś nie musiał ustalać tego przed każdym exitosobno). W dowolnym miejscu „na początku” w skrypcie:

trap 'git update-ref -m "removing HEAD after temporary checkout to alternate workdir" -d HEAD "$NEW_SHA1"' 0

Jeśli twoje repozytorium nie jest puste lub chcesz zachować referencję HEAD (tak, aby klony domyślnie sprawdzały inną gałąź), musisz zapisać referencję HEAD i przywrócić ją przed wyjściem.

Po pierwsze, w repozytorium serwera zresetuj odniesienie HEAD, aby wskazać gałąź, którą chcesz domyślnie wypisać w nowych klonach:

git symbolic-ref -m 'setting default branch for new clones' HEAD refs/heads/master

Następnie w skrypcie przechwytującym (gdziekolwiek przed kasą):

# Restore HEAD symref when exiting
saved_HEAD=$(git symbolic-ref HEAD)
trap 'git symbolic-ref -m "restoring HEAD after temporary checkout to alternate workdir" HEAD "$saved_HEAD"' 0

Nawiasem mówiąc, pre-receivehaki powinny upewnić się, że w pełni odczytują standardowe wejście i przetwarzają wszystkie linie, które są karmione. Wyjście przed zużyciem wszystkich danych wejściowych może czasami wyzwalać SIGPIPE w tym git-receive-packprocesie; prawdopodobnie nie pojawia się to w twoim przypadku, jeśli naciskasz tylko jeden odnośnik na raz (ponieważ czytasz co najmniej jedną linię), ale należy o tym pamiętać. Prawdopodobnie łatwiej jest zrobić ten hak jako updatehaczyk, w którym musisz zajmować się tylko jednym refem na raz i możesz odepchnąć każdy ref z osobna (może zależy ci tylko na utrzymaniu czystości końcówki mistrza ; podczas sprawdzania i zgłaszać wskazówki innych gałęzi, ale nigdy ich nie odrzucać, aby można je było wykorzystać do współpracy przy niepełnej pracy).

Chris Johnsen
źródło