git, nagios dan hooks, git repo rusak

14

Latar Belakang

Kami menggunakan nagios untuk memantau infrastruktur kami. Kami tidak memiliki konfigurasi nagios di bawah kontrol versi saat ini, dan ada dua dari kami yang mengelola konfigurasi nagios. Karena itu, saya sedang berusaha untuk membuat konfigurasi nagios kami menjadi repo git pusat, menggunakan beberapa kait untuk melakukan pemeriksaan sintaks dan kemudian jika konfigurasi terlihat bagus, buat mereka "aktif". Saya menggunakan pos orang ini sebagai titik awal.

Alur kerja umum yang saya coba terapkan adalah:

  1. Edit git repo lokal dari nagios config. Tambahkan file yang diedit, komit secara lokal.
  2. git push origin master ke repo jarak jauh.
  3. Push dicegat oleh kait pra-terima, yang mengambil file, memindahkannya ke direktori sementara di server, dan menjalankannya melalui pemeriksa sintaksis nagios.
  4. Jika pemeriksa sintaks berhasil, terima push, kemudian gunakan post-commit hook ke git pullkode baru ke direktori konfigurasi live nagios dan kemudian mulai kembali nagios.
  5. Jika pemeriksa sintaks gagal, tolak push, yang menunjukkan kesalahan sintaksis nagios kepada pengguna.

Saya mengalami perilaku aneh, ketika saya menolak dorongan git karena kesalahan sintaks di konfigurasi nagios. Apa yang saya harapkan terjadi adalah bahwa jika saya menolak kail, upaya yang dicoba harus meninggalkan repositori seperti itu, tidak tersentuh. Tapi sepertinya itu tidak terjadi. Berikut adalah detail dari apa yang saya lihat:

Masalah

Saya mengedit konfigurasi nagios secara lokal, dengan sengaja memasukkan kesalahan sintaks, menambahkan, lalu melakukan secara lokal:

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

Sekarang saya mendorong perubahan itu ke master repo. Ini akan ditolak karena kesalahan sintaksis:

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'

Seharusnya ini tidak menyentuh repo jarak jauh, tapi itu benar. Jika saya mengubah ke direktori temp lokal lain dan mencoba mengkloning repo, saya mendapatkan:

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

Sekarang saya kembali ke direktori kerja asli, perbaiki kesalahan sintaksis, tambahkan, komit, dan dorong:

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

Pada titik ini, repositori baik-baik saja, dan saya dapat mengubah ke direktori sementara dan mengkloning repo lagi:

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.

Ini adalah kait pra-terima yang saya gunakan.

Saya menggunakan git v1.7.5.4 di klien, dan v1.7.2.3 di server.

Jadi, untuk pertanyaan : mengapa repositori dibiarkan dalam keadaan tidak konsisten ketika saya menolak push? Apakah ada sesuatu yang salah dengan git hook saya atau mungkin pemahaman saya tentang git kurang?

EEAA
sumber
Apa versi git yang Anda gunakan?
robbyt
@robbyt - 1.7.5.4di klien, 1.7.2.3di server.
EEAA

Jawaban:

7

Kamu lakukan:

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

di kait Anda. Meskipun tidak menyentuh biasa kerja-menyalinnya adalah memperbarui referensi dalam git-dir (khususnya HEADreferensi), seperti yang ditunjukkan pada kesalahan Anda:

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

Hook Anda lakukan exit 1untuk menolak pembaruan, tetapi itu bukan (mengatur ulang) HEADreferensi setelah kegagalan.

Saya pikir Anda perlu memperbarui cabang kegagalan di hook Anda seperti:

...
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
   ...
pendatang
sumber
Ini terlihat hebat, haji. Saya akan coba sedikit nanti hari ini. Terima kasih!
EEAA
0

The git checkoutperintah dalam kail Anda adalah menciptakan / memperbarui ref KEPALA dalam repositori Anda.

Jika repositori Anda adalah repositori kosong, ia dapat hidup tanpa referensi HEAD (klon baru akan secara default memeriksa cabang masternya , jika ada); hapus saja HEAD ref sebelum keluar (mungkin trapagar Anda tidak perlu mengatur untuk melakukannya sebelum masing exit- masing secara individu). Di mana saja "awal" dalam skrip Anda:

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

Jika repositori Anda tidak kosong, atau Anda ingin mempertahankan referensi HEAD (sehingga klon akan, secara default, memeriksa beberapa cabang lainnya), maka Anda harus menyimpan referensi HEAD dan mengembalikannya sebelum keluar.

Pertama, di repositori server, reset ref HEAD untuk menunjuk ke cabang yang ingin Anda periksa secara default di klon baru:

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

Lalu, di skrip kait Anda (di mana saja sebelum checkout):

# 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

Ngomong-ngomong, pre-receivepengait harus memastikan bahwa mereka sepenuhnya membaca stdin dan memproses semua baris yang diumpankan. Keluar sebelum mengkonsumsi semua input terkadang dapat memicu SIGPIPE dalam git-receive-packproses; ini mungkin tidak muncul dalam kasus Anda jika Anda hanya mendorong satu referensi pada satu waktu (karena Anda membaca setidaknya satu baris), tetapi itu adalah sesuatu yang perlu diingat. Mungkin lebih mudah untuk melakukan hook ini sebagai updatehook di mana Anda hanya perlu peduli dengan satu ref pada satu waktu dan dapat menolak setiap dorongan ref secara individual (mungkin Anda hanya peduli menjaga ujung master "bersih"; saat Anda memeriksa dan melaporkan tip dari cabang lain, tetapi jangan pernah menolaknya sehingga mereka dapat digunakan untuk kolaborasi pada pekerjaan yang tidak lengkap).

Chris Johnsen
sumber