Фон
Мы используем nagios для мониторинга нашей инфраструктуры. На данный момент у нас нет конфигураций nagios под управлением версиями, и есть двое из нас, которые управляют конфигурацией nagios. Поэтому я работаю над тем, чтобы перенести наш конфиг nagios в центральное git-репо, используя некоторые хуки для проверки синтаксиса, а затем, если конфиги выглядят хорошо, сделать их «активными». Я использую пост этого парня в качестве отправной точки.
Общий рабочий процесс, который я пытаюсь реализовать:
- Отредактируйте локальное git-репозиторий config nagios. Добавить отредактированные файлы, зафиксировать локально.
git push origin master
на удаленный репо.- Push перехватывается перехватчиком предварительного приема, который берет файлы, перемещает их во временный каталог на сервере и запускает их через средство проверки синтаксиса nagios.
- Если проверка синтаксиса пройдена, примите push, затем используйте перехват фиксации для
git pull
нового кода в каталоге конфигурации live nagios, а затем перезапустите nagios. - Если проверка синтаксиса завершается неудачно, отклоните push-запрос, показывая пользователю синтаксическую ошибку nagios.
Однако я сталкиваюсь со странным поведением, когда отклоняю команду git push из-за синтаксических ошибок в конфигурации nagios. Что я ожидаю, так это то, что если я отклоню хук, попытка push-кода должна оставить хранилище таким, каким оно было, без изменений. Это, похоже, не тот случай. Ниже приведены детали того, что я вижу:
проблема
Я редактирую конфигурацию 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 на сервере.
Итак, на вопрос : почему хранилище остается в несогласованном состоянии, когда я отклоняю push? Что-то не так с моим git hook или, может быть, мне не хватает понимания git?
1.7.5.4
на клиенте,1.7.2.3
на сервере.Ответы:
Ты поживаешь:
в твоем крючке Хотя это не касается вашей обычной рабочей копии она будет обновлять ссылки в мерзавца-каталог ( в частности,
HEAD
ссылка), как показано на своей ошибке:Ваша ловушка делает,
exit 1
чтобы отклонить обновление, но не сбрасывает (повторно)HEAD
ссылку после сбоя.Я думаю, что вам нужно обновить ветку сбоев в вашем хуке так:
источник
git checkout
в вашем хуке создает / обновляет ссылку HEAD в вашем хранилище.Если ваш репозиторий является пустым репозиторием, он может жить без ссылки на HEAD (новые клоны по умолчанию будут проверять свою основную ветку, если она есть); просто удалите ссылку HEAD перед выходом (возможно,
trap
так, чтобы вам не приходилось делать это перед каждым поexit
отдельности). В любом месте «рано» в вашем сценарии:Если ваш репозиторий не пустой, или вы хотите сохранить ссылку на HEAD (так, чтобы клоны по умолчанию проверяли какую-то другую ветку), вам придется сохранить ссылку на HEAD и восстановить ее перед выходом.
Сначала в репозитории сервера сбросьте ссылку HEAD так, чтобы она указала на ветку, которую вы хотите по умолчанию извлекать в новых клонах:
Затем в вашем скрипте хука (где угодно до оформления заказа):
Кстати,
pre-receive
хуки должны убедиться, что они полностью читают стандартный ввод и обрабатывают все строки, которые им передаются. Выход перед использованием всех входных данных может иногда вызывать SIGPIPE вgit-receive-pack
процессе; это, вероятно, не подходит в вашем случае, если вы нажимаете только одну ссылку за раз (поскольку вы читаете хотя бы одну строку), но об этом следует помнить. Вероятно, проще сделать этот хук какupdate
хук, когда вам нужно иметь дело только с одним рефером за раз и вы можете отклонять толчок каждого рефера индивидуально (может быть, вам нужно только поддерживать кончик мастера «чистым»; пока вы проверяете и сообщайте о советах других веток, но никогда не отклоняйте их, чтобы их можно было использовать для совместной работы при неполной работе).источник