git, nagios และ hooks, repo คอมไพล์ที่เสียหาย


14

พื้นหลัง

เรากำลังใช้ nagios เพื่อตรวจสอบโครงสร้างพื้นฐานของเรา เราไม่มีการกำหนดค่า nagios ภายใต้การควบคุมเวอร์ชันในขณะนี้และเราสองคนที่จัดการการกำหนดค่า nagios เช่นนี้ฉันกำลังทำงานเพื่อให้ nagios ของเราตั้งค่าเป็น git repo ส่วนกลางโดยใช้ hooks เพื่อทำการตรวจสอบไวยากรณ์แล้วถ้าค่าปรับนั้นดูดีทำให้พวกมันใช้งานได้ ฉันใช้โพสต์ของผู้ชายคนนี้เป็นจุดเริ่มต้น

เวิร์กโฟลว์ทั่วไปที่ฉันพยายามใช้คือ:

  1. แก้ไข repit คอมไพล์ท้องถิ่นของ nagios config เพิ่มไฟล์ที่แก้ไขแก้ไขกระทำในเครื่อง
  2. git push origin master ไปยัง repo ระยะไกล
  3. Push ถูกดักจับโดย hook การรับล่วงหน้าซึ่งใช้ไฟล์ย้ายไปยังไดเร็กทอรีชั่วคราวบนเซิร์ฟเวอร์และรันผ่านทาง nagios syntax checker
  4. หากตัวตรวจสอบไวยากรณ์ผ่านไปให้ยอมรับการพุชจากนั้นใช้ hook post-commit เพื่อgit pullโค้ดใหม่ลงในไดเร็กทอรีการกำหนดค่า live nagios จากนั้นรีสตาร์ท nagios
  5. หากตัวตรวจสอบไวยากรณ์ล้มเหลวให้ปฏิเสธการพุชและแสดงข้อผิดพลาดทางไวยากรณ์ของ nagios ให้กับผู้ใช้

ฉันกำลังทำงานผิดปกติ แต่เมื่อฉันปฏิเสธการ git push เนื่องจากข้อผิดพลาดทางไวยากรณ์ใน nagios config สิ่งที่ฉันคาดหวังว่าจะเกิดขึ้นคือถ้าฉันปฏิเสธเบ็ดการพยายามทำแบบนั้นควรจะออกจากพื้นที่เก็บข้อมูลเหมือนที่เคยเป็นมา แม้ว่าจะไม่เป็นเช่นนั้น ด้านล่างนี้เป็นรายละเอียดของสิ่งที่ฉันเห็น:

ปัญหา

ฉันแก้ไข nagios config ในเครื่องโดยเจตนารวมถึงข้อผิดพลาดทางไวยากรณ์เพิ่มจากนั้นส่งคอมมิท:

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

ตอนนี้ฉันผลักดันการเปลี่ยนแปลงเหล่านั้นไปที่ repo หลัก สิ่งนี้จะถูกปฏิเสธเนื่องจากข้อผิดพลาดทางไวยากรณ์:

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'

สิ่งนี้ไม่ควรแตะ repo ทางไกล แต่ทำเช่นนั้น ถ้าฉันเปลี่ยนไปเป็นไดเรกทอรีชั่วคราวในพื้นที่อื่นและพยายามโคลน repo ฉันจะได้รับ:

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

ณ จุดนี้พื้นที่เก็บข้อมูลใช้ได้และฉันสามารถเปลี่ยนเป็นไดเรกทอรีชั่วคราวและลอกแบบ repo อีกครั้ง:

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 บนเซิร์ฟเวอร์

ดังนั้นคำถาม : ทำไมที่เก็บถูกทิ้งให้อยู่ในสถานะที่ไม่สอดคล้องกันเมื่อฉันปฏิเสธการผลักดัน? มีบางอย่างผิดปกติกับเบ็ดคอมไพล์ของฉันหรือบางทีความเข้าใจของฉันเกี่ยวกับคอมไพล์ขาด


คุณใช้คอมไพล์รุ่นใด
robbyt

@robbyt - 1.7.5.4บนไคลเอนต์1.7.2.3บนเซิร์ฟเวอร์
EEAA

คำตอบ:


7

คุณกำลังทำ:

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

ในเบ็ดของคุณ แม้ว่ามันจะไม่ได้สัมผัสกับสำเนาทำงานปกติของคุณ แต่มันก็กำลังอัพเดทการอ้างอิงใน git-dir (โดยเฉพาะการ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 (โคลนใหม่จะเริ่มต้นการตรวจสอบสาขาหลักของมันถ้ามันมี) เพียงแค่ลบการอ้างอิง HEAD ก่อนออก (อาจเป็นไปได้trapเพื่อที่คุณจะได้ไม่ต้องจัดการก่อนแต่ละexitที) ทุกที่ "ก่อน" ในสคริปต์ของคุณ:

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

หากพื้นที่เก็บข้อมูลของคุณไม่ได้เปลือยเปล่าหรือคุณต้องการรักษาการอ้างอิง HEAD (โดยค่าเริ่มต้นโคลนจะตรวจสอบสาขาอื่น ๆ ) จากนั้นคุณจะต้องบันทึกการอ้างอิง HEAD และเรียกคืนก่อนออก

ขั้นแรกในที่เก็บของเซิร์ฟเวอร์รีเซ็ตการอ้างอิง 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-receivehooks ควรตรวจสอบให้แน่ใจว่าพวกเขาอ่าน stdin อย่างเต็มที่และประมวลผลทุกบรรทัดที่พวกเขาจะถูกป้อน การออกก่อนที่จะใช้อินพุตทั้งหมดบางครั้งสามารถทริกเกอร์ SIGPIPE ในgit-receive-packกระบวนการ สิ่งนี้อาจไม่ได้เกิดขึ้นในกรณีของคุณหากคุณกดการอ้างอิงครั้งละหนึ่งรายการเท่านั้น (เนื่องจากคุณอ่านอย่างน้อยหนึ่งบรรทัด) แต่เป็นสิ่งที่คุณควรคำนึงถึง บางทีมันอาจจะเป็นเรื่องง่ายที่จะทำเบ็ดนี้เป็นupdateตะขอที่คุณต้องการเพียงเพื่อจะเกี่ยวข้องกับหนึ่งเตะในเวลาและสามารถปฏิเสธการผลักดันแต่ละเตะของรายบุคคล (บางทีคุณอาจจะดูแลเกี่ยวกับการรักษาปลายของหลัก “สะอาด” ในขณะที่คุณตรวจสอบและ รายงานเคล็ดลับของสาขาอื่น ๆ แต่อย่าปฏิเสธพวกเขาเพื่อให้พวกเขาสามารถใช้สำหรับการทำงานร่วมกันในการทำงานที่ไม่สมบูรณ์)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.