git, nagios and hooks, пошкоджена git repo


14

Фон

Ми використовуємо nagios для моніторингу нашої інфраструктури. Наразі у нас немає конфігурацій nagios під контролем версій, і є двоє з нас, які керують конфігурацією nagios. Таким чином, я працюю над тим, щоб наші конфігурації нагіосів перейшли в центральний репост git, використовуючи деякі гачки для перевірки синтаксису, а потім, якщо конфігурації виглядають добре, зробіть їх "активними". Я використовую пост цього хлопця як вихідний пункт.

Загальний робочий процес, який я намагаюся реалізувати, це:

  1. Редагувати локальну git repo конфігурації nagios. Додайте відредаговані файли, введіть локально.
  2. git push origin master до віддаленого репо.
  3. Push перехоплюється гаком попереднього отримання, який приймає файли, переміщує їх у тимчасовий каталог на сервері та запускає їх через перевірку синтаксису nagios.
  4. Якщо перевірка синтаксису проходить, прийміть поштовх, а потім використовуйте гачок після фіксації git pullнового коду до каталогу конфігурації живих nagios, а потім перезапустіть nagios.
  5. Якщо перевірка синтаксису не працює, відхиліть натискання, показуючи користувачеві синтаксичну помилку нагіосу.

Однак я стикаюся з дивною поведінкою, коли відхиляю git push через синтаксичні помилки в конфігурації nagios. Я очікую, що це станеться, що якщо я відхиляю гачок, спроба натиснути повинна залишити сховище так, як воно було, недоторканим. Але, здається, це не так. Нижче наведено деталі того, що я бачу:

Проблема

Я редагую налаштування nagios локально, навмисно включаючи синтаксичну помилку, додаю, а потім здійснюю локально:

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(-)

Тепер я підштовхую ці зміни до головного репо. Це буде відхилено через синтаксичну помилку:

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 git@remote-server.example.com:nagios
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'git@remote-server.example.com:nagios'

Це не повинно було торкатися віддаленого репо, але це було. Якщо я перейду на інший локальний тимчасовий каталог і спробую клонувати репо, я отримаю:

host:temp erik$ git clone git@remote-server.example.com: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'.

Тепер я повертаюся до початкового каталогу роботи, виправляю синтаксичну помилку, додаю, фіксую і натискаю:

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 git@remote-server.example.com:nagios
   3ddc880..f147ded  master -> master

На даний момент сховище добре, і я можу перейти у тимчасовий каталог і знову клонувати репо:

host:temp erik$ git clone git@remote-server.example.com: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.

Ось гачок попереднього отримання, який я використовую.

Я використовую git v1.7.5.4 на клієнті, а v1.7.2.3 на сервері.

Отже, до питання : чому сховище залишається в непослідовному стані, коли я відхиляю натискання? Щось кривавого з моїм гаком чи ні, можливо, не вистачає мого розуміння git?


Яку версію git ви використовуєте?
robbyt

@robbyt - 1.7.5.4на клієнті, 1.7.2.3на сервері.
ЄЕАА

Відповіді:


7

Ти робиш:

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

у вашому гачку. Хоча це не стосується вашої звичайної робочої копії вона буде оновлювати посилання в мерзотника-каталог ( в Зокрема, HEADпосилання), як показано на своїй помилці:

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

Ваш гак робить, exit 1щоб відхилити оновлення, але це не (повторно) скидання HEADпосилання після відмови.

Я думаю, вам потрібно так оновити гілку відмови у вашому гачку:

...
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
   ...

Це чудово виглядає, нікльгриме. Я спробую трохи пізніше сьогодні. Дякую!
EEAA

0

git checkoutКоманда в вашому гачку створює / поновлення ГОЛОВИ реф в вашому сховищі.

Якщо ваш сховище є голим сховищем, він може жити без HEAD ref (нові клони за замовчуванням перевіряють його головну гілку, якщо вона має); просто видаліть HEAD ref перед виходом (можливо, trapтаким чином, що вам не доведеться домовлятися робити це перед кожним exitокремо). У будь-якому місці "рано" у вашому сценарії:

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

Якщо ваш сховище не є голим, або ви хочете підтримувати посилання HEAD (щоб клони за замовчуванням перевірили якусь іншу гілку), вам доведеться зберегти HEAD ref і відновити його перед виходом.

По-перше, у сховищі сервера скиньте посилання HEAD, щоб вказати на гілку, яку ви хочете перевірити за замовчуванням у нових клонах:

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

Потім у вашому сценарії гака (будь-де до оформлення замовлення):

# 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

До речі, pre-receiveгачки повинні переконатися, що вони повністю читають stdin та обробляють усі рядки, якими вони подаються. Вихід до споживання всього введення може іноді викликати SIGPIPE в git-receive-packпроцесі; це, мабуть, не приходить у вашому випадку, якщо ви одночасно натискаєте лише один посилання (оскільки ви прочитали принаймні один рядок), але це потрібно пам’ятати. Напевно, простіше зробити цей гачок як updateгачок, коли вам потрібно зайнятись лише однією рефлексією за один раз, і ви можете відхилити натискання кожного рефлексу окремо (можливо, ви дбаєте лише про те, щоб наконечник майстра був «чистим»; поки ви перевіряєте і повідомляти про поради інших галузей, але ніколи не відкидайте їх, щоб їх можна було використовувати для співпраці при незавершеній роботі).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.