اذهب إلى المحتوى

كيفية بناء خادم جيت لـ Git


هدى جبور

سنتعلم في هذا المقال كيفية إنشاء خادم جيت Git، وكيفية كتابة خطّافات جيت Git hooks مخصصة لتشغيل إجراءات معينة (مثل الإشعارات) قبل أو بعد أحداث محددة، إضافةً إلى نشر شيفراتك البرمجية على موقع ويب.

لحد هذه اللحظة كان حديثنا في السلسلة عن جيت كمستخدمين، أما الآن ستتم مناقشة إدارة جيت وتصميم بنية تحتية مرنة لجيت. قد تعتقد أن الأمر متقدم أو يحتاج إلى خبرة متقدمة، ولكن في الواقع لا يتطلب معرفة متقدمة أو أي تدريب خاص يتجاوز الفهم المتوسط لكيفية عمل جيت، والقليل من المعرفة حول لينكس.

خادم جيت المشترك

إن إنشاء خادم جيت مشترك خاص بك يعد أمرًا بسيطًا للغاية، وفي كثير من الحالات يستحق العناء، فهو لا يضمن فقط إمكانية الوصول إلى شيفرتك البرمجية دائمًا، بل تفتح أيضًا الأبواب لتوسيع مدى وصول جيت بامتدادات مثل خطافات جيت الخاصة، وتخزين غير محدود للبيانات، والدمج والنشر المستمر.

إذا كان لديك معرفة حول كيفية استخدام جيت والتعامل مع خدمة SSH، فأنت تعرف من حيث لا تدري كيفية إنشاء خادم جيت. عندما تُنشئ مستودع أو عندما تنسخه من أحد المصادر، فإنك تكون قد أعددت عمليًّا نصف الخادم. بعد إعداد المستودع يجب تمكين الاتصال من خلال خدمة SSH مع المستودع، وبعدها يمكن لأي شخص لديه حق الوصول أن يستخدم المستودع كأساس لنسخة جديدة.

عمومًا، تمثل هذه الطريقة واحدة من الطرق المتبعة لإنشاء خادم جيت git server، حيث هناك طرق أخرى تمكنك من إنشاء خادم جيت مصمم جيدًا وتقريبًا بنفس القدر من الجهد ومع قابلية تطوير أفضل. بدايةً يجب عليك تحديد المستخدمين الحاليين والمستقبليين، أما إذا كنت المستخدم الوحيد فلا داعي لإجراء أي تغييرات، ولكن إذا كنت تنوي إشراك مساهمين، فلا بد من تحديدهم.

بفرض كان لديك خادم متاح (ليست مشكلة إذا لم يكن لديك خادم، حيث أن جيت يمكنها أن تساعدك في حل هذه المشكلة، كما أنه بإمكانك استخدام حاسوب راسبيري باي على نظام CentOS كمخدم في البداية)، فإن الخطوة الأولى هي تمكين عمليات تسجيل الدخول عبر خدمة SSH باستخدام ترخيص مفتاح SSH فقط، ويعد هذا أقوى بكثير من عمليات تسجيل الدخول باستخدام كلمة المرور لأنه محصن ضد هجمات القوة الغاشمة brute-force (طرق الاختراق التي تعتمد على تجريب كافة الاحتمالات الممكنة) كما أنه يمكن تعطيل المستخدم ببساطة من خلال حذف مفتاحه.

بمجرد تمكين المصادقة من خلال مفتاح SSH أنشئ مستخدم جيت gituser، وهو عبارة عن مستخدم مشترك لجميع المستخدمين المُصرّح لهم:

$ su -c 'adduser gituser'

ثم قم بالتبديل إلى هذا المستخدم، وأنشئ إطار عمل ‎~/.ssh مع الأذونات المناسبة، وهذا مهم من أجل حمايتك، فإن لم تضع الأذونات اللازمة ستفشل فكرة استخدام مفتاح SSH للحماية.

$ su - gituser
$ mkdir .ssh && chmod 700 .ssh
$ touch .ssh/authorized_keys
$ chmod 600 .ssh/authorized_keys

يحتوي ملف authorized_keys على مفاتيح SSH العامة لجميع المطورين الذين تمنحهم الإذن للعمل في مشروعك على جيت، وينبغي من كل مطوريك إنشاء أزواج من مفاتيح SSH الخاصة بهم وإرسال مفاتيحهم العامة إليك، وأنت ينبغي عليك نسخ المفاتيح العامة في ملف authorized_keys الخاص بمستخدم جيت (انظر مقال العمل مع خواديم SSH: العملاء والمفاتيح)، على سبيل المثال بالنسبة لمطور يسمى Bob، قم بتشغيل هذه الأوامر:

$ cat ~/path/to/id_rsa.bob.pub >> \
/home/gituser/.ssh/authorized_keys

طالما أن المطور Bob مثلًا لديه المفتاح الخاص الذي يطابق المفتاح العام الذي أرسله إليك، يمكن للمطور Bob الوصول إلى الخادم باعتباره مستخدم جيت.

عمومًا، قد لا ترغب في منح مطوريك حق الوصول إلى خادمك، حتى لو كان الوصول كمستخدم جيت فقط، وتريد فقط منحهم حق الوصول إلى مستودع جيت، لهذا السبب يوفر جيت صدفة shell تسمى git-shell.

نفّذ هذه الأوامر (كمستخدم جذر root) لإضافة git-shell إلى نظامك، ثم اجعلها الصدفة الافتراضية لمستخدم جيت:

# grep git-shell /etc/shells || su -c \
"echo `which git-shell` >> /etc/shells"
# su -c 'usermod -s git-shell gituser'

الآن يمكن لمستخدم جيت استخدام مفتاح SSH فقط لدفع وسحب مستودعات جيت، ولا يمكنه الوصول إلى قشرة تسجيل الدخول. ينبغي عليك أيضًا أن تُضف نفسك إلى المجموعة المقابلة لـمستخدم جيت، والتي في مثالنا يمثلها الخادم الذي يعتبر أيضًا مستخدم جيت.

فمثلًا:

# usermod -a -G gituser seth

الخطوة الوحيدة المتبقية هي إنشاء مستودع جيت، ونظرًا لأن لا أحد سيتفاعل معه مباشرة على الخادم (أي أنك لن تذهب إلى SSH الخاص بالخادم وتعمل مباشرة في هذا المستودع)، اجعله مستودعًا خاليًا، وإذا كنت ترغب في استخدام المستودع على الخادم لإنجاز العمل، فانسخه من هناك واعمل عليه في المجلد الرئيسي الخاص بك.

في الحقيقة، ليس عليك فعليًّا أن تجعل هذا المستودع فارغًا؛ بإمكانه العمل كمستودع عادي، لكن يجب أن تعلم أن المستودع المجرد bare repository لا يحتوي على شجرة عمل working tree، أي لا توجد فيه فروع للتنقل بينها من خلال أمر checkout، وهذا مهم (أن يكون مجردًا) لأنه لا يُسمح للمستخدمين البعيدين بالانتقال إلى فرع نشط (أي يتم العمل عليه حاليًّا)، فمن المؤكد أنك لن تكون سعيدًا في حال كنت تعمل على فرع ما وليكن "Dev" وفجأة يأتي شخص ويدفع تعديلاته ضمن عملك!

يمكنك وضع هذا المستودع في أي مكان تريده، طالما أن المستخدمين والمجموعات الذين تريد منحهم إذنًا للوصول إليه يمكنهم فعل ذلك.

إن لم ترد وضع المجلد في المجلد الرئيسي، مثلًا لأن الأذونات فيه حازمة ودقيقة للغاية، وتريد تخزينه في موقع آخر مثل ‎/opt أو /usr/local/share، فأنشئ مستودعًا مجردًا كمستخدم جذر:

# git init --bare /opt/jupiter.git
# chown -R gituser:gituser /opt/jupiter.git
# chmod -R 770 /opt/jupiter.git

الآن يمكن لأي مستخدم تمت مصادقته على أنه مستخدم جيت أو موجود في مجموعة مستخدم جيت أن ينفذ عمليات القراءة من مستودع jupiter.git والكتابة عليه.

يمكنك تجريبه على جهازك كالتالي:

$ git clone gituser@example.com:/opt/jupiter.git jupiter.clone
Cloning into 'jupiter.clone'...
Warning: you appear to have cloned an empty repository.

تذكر أنه يجب على المطورين إدخال مفتاح SSH العام الخاص بهم في ملف authorized_keys الخاص بمستخدم جيت، أو إذا كان لديهم حسابات على الخادم مثلك، فيجب أن يكونوا أعضاء في مجموعة مستخدم جيت.

خطافات جيت git hooks

إحدى الميزات الرائعة لاستخدام خادم جيت خاص بك هو أنه يتيح لك استخدام الخطافات، وهي برامج يتم تنفيذها قبل أو بعد أحداث محددة كالإيداع والسحب والدفع …إلخ. وبمزيد من الدقة هو ملف تنفيذي يتم وضعه في مجلد ‎.git/hooks واعتمادًا على مخطط تسمية قياسي يتم تنفيذه في الوقت المحدد، ويمكنك كتابة الشيفرة البرمجية التي ينفذها الخطاف بأي لغة تريدها، أي أنك غير مجبر على استخدام لغة محددة.

أحيانًا توفر خدمات استضافة جيت واجهة تشبه الخطاف، لكنها لا تمنحك روابط جيت حقيقية ولا حتى إمكانية الوصول إلى نظام الملفات، وسنرى الآن مثالًا لاستخدام الخطافات، وهذا يتطلب منك إنشاء مستودع جيت إذا لم يكن لديك واحد بالفعل:

$ mkdir jupiter
$ cd jupiter
$ git init

ثم أنشئ خطاف جيت يعرض الرسالة "hello world":

$ echo "#\!/bin/tcsh" > .git/hooks/post-commit
$ echo "echo 'POST-COMMIT SCRIPT TRIGGERED'" >> \
~/jupiter/.git/hooks/post-commit
$ chmod +x ~/jupiter/.git/hooks/post-commit

والآن اختبره:

$ echo "hello world" > foo.txt
$ git add foo.txt
$ git commit -m 'first commit'
! POST-COMMIT SCRIPT TRIGGERED
[master (root-commit) c8678e0] first commit
1 file changed, 1 insertion(+)
create mode 100644 foo.txt

والآن أصبح لدينا خطاف جاهز ونشط.

خطاف الدفع إلى الويب

الاستخدام الشائع لخطافات جيت هو دفع التعديلات تلقائيًا إلى المجلد الموجود على خادم ويب إنتاجي، حيث أنها تعتبر طريقة رائعة للتخلي عن بروتوكول نقل الملفات FTP، والاحتفاظ بكامل التحكم في الإصدار لما هو قيد الإنتاج، ودمج ونشر المحتوى تلقائيًا. إذا تم إنجازه بطريقة صحيحة، فإنه سيعمل بروعة، وفعليًّا هكذا يجب أن تتم عمليات النشر على الويب.

متغيرات جيت

يتم تخصيص مجموعة مختلفة من المتغيرات المتعلقة بالإجراء الذي يتم تنفيذه لكل خطاف، وربما تحتاج أو لا تحتاج إلى استخدام هذه المتغيرات، حيث يعتمد ذلك على ما تكتبه، فإذا كان كل ما تريده هو رسالة بريد إلكتروني عامة تنبهك إلى أن شخصًا ما نفّذ عملية دفع، فأنت لست بحاجة إلى تفاصيل، وربما قد لا تحتاج حتى إلى كتابة البرنامج، أما إذا كنت تريد رؤية رسالة الإيداع ومؤلف الإيداع في هذا البريد الإلكتروني، فلا بد من البرنامج آنذاك.

لا يتم تشغيل خطافات جيت من خلال المستخدم مباشرةً، لذا قد تكون معرفة كيفية جمع المعلومات المهمة أمرًا محيرًا. حقيقةً، يشبه خطاف جيت أي نص برمجي آخر، حيث يستلم المعطيات من مجرى الدخل القياسي stdin بنفس طريقة باش BASH وبايثون Python وسي بلس بلس C++‎ وأي لغة أخرى. الفرق هو أننا لا نقدم هذه المدخلات بأنفسنا، لذا لاستخدامها عليك أن تعرف ما يمكن توقعه.

قبل إنشاء خطاف جيت، انظر إلى العينات التي يوفرها جيت في مجلد ‎.git/hooks‎ الخاص بمشروعك مثل ملف pre-push.sample، وانظر إلى ما ينصّه في قسم التعليقات:

# $1 -- اسم المستودع البعيد الذي يتم إجراء عملية دفع إليه
# $2  للمستودع البعيد URL عنوان 
# إذا تمت عملية الدفع من دون استخدام اسم المستودع البعيد، فإن هذه المعطيات ستكون متساوية
# يتم توفير معلومات تتعلق بالإيداع كما يلي
# <local ref> <local sha1> <remote ref> <remote sha1>

في الحقيقة ليست كل العينات واضحة إلى هذه الدرجة كما في العينة السابقة، ولا يزال توثيق مجموعة المتغيرات التي يتم تمريرها كمعطيات إلى الخطافات قليلًا (بإمكانك قراءة الشيفرة المصدرية لجيت لمعرفتها، لكن لا أعتقد أنك سترغب في ذلك).

مثال عن الخطافات التي تنجز مهام محددة بناءً على الفرع المُتأثر

يُعتبر الخطاف الذي يُنفذ إجراءات معينة ضمن فرع محدد، أحد المتطلبات الشائعة في بعض الأنظمة البرمجية، وفيما يلي مثال على كيفية التعامل مع مثل هذه المهمة.

قبل كل شيء يجب أن تعلم أن جيت لا تتبع الخطافات الخاصة بها لأن الخطاف يعد جزءًا من جيت وليس جزءًا من مستودعك، ولهذا السبب خطافات جيت التي تشرف على عمليات الإيداع والدفع ربما يكون من المنطقي أكثر بقاءها في المستودع المجرد على الخادم، بدلاً من أن تكون جزءًا من مستودعاتك المحلية.

سنكتب الآن خطافًا يتم تنفيذه بعد استلام الإيداع، الخطوة الأولى هي تحديد اسم الفرع:

#!/bin/tcsh

foreach arg ( $< )
  set argv = ( $arg )
  set refname = $1
end

تقرأ حلقة for-loop هذه المُعطى الأول $1، ثم تعيد التكرار من أجل استبداله بالمُعطى الثاني ‎$2، ثم مرة أخرى من أجل المعطى الثالث ‎$3. هناك طريقة أفضل للقيام بذلك في باش Bash، عن طريق استخدام الأمر read ووضع القيم في مصفوفة.

عندما يكون لدينا اسم المرجع refname للشيء الذي يتم إيداعه، يمكننا استخدام جيت لاكتشاف اسم الفرع المقروء:

set branch = `git rev-parse --symbolic --abbrev-ref $refname`
echo $branch #DEBUG

بعد ذلك وازن اسم الفرع بالكلمات المفتاحية التي نريد أن نبني الإجراء عليها:

if ( "$branch" == "master" ) then
  echo "Branch detected: master"
  git \
    --work-tree=/path/to/where/you/want/to/copy/stuff/to \
    checkout -f $branch || echo "master fail"
else if ( "$branch" == "dev" ) then
  echo "Branch detected: dev"
  Git \
    --work-tree=/path/to/where/you/want/to/copy/stuff/to \
    checkout -f $branch || echo "dev fail"
  else
    echo "Your push was successful."
    echo "Private branch detected. No action triggered."
endif

الآن نحوّل الشيفرة البرمجية إلى ملف تنفيذي:

$ chmod +x ~/jupiter/.git/hooks/post-receive

الآن عندما ينفذ المستخدم إيداعًا ضمن الفرع الرئيسي للخادم، يتم نسخ الشيفرة البرمجية إلى مجلد العمل، والإيداع ضمن الفرع dev يتم نسخه في مكان آخر، ولا يحدث أي إجراء في الفروع الأخرى.

من السهل جدًا إنشاء برنامج للإيداع المسبق، مثلًا يتحقق فيما إذا كان شخص ما يحاول الدفع إلى فرع لا ينبغي أن يتم الدفع إليه، أو لتحليل رسائل الإيداع وما إلى ذلك.

يمكن أن تكون خطافات جيت معقدة، ويمكن أن تكون مربكة بسبب مستوى التجريد الذي يفرضه العمل من خلال جيت، لكنها نظام قوي يسمح لك بتصميم جميع أنواع الإجراءات في البنية التحتية لجيت، لذلك فهي تستحق أن تتقنها.

سوف نتعلم في المقال التالي والأخير من هذه السلسلة كيفية استخدام جيت لإدارة الكائنات الثنائية غير النصية، مثل ملفات الصوت والرسومات.

ترجمة -وبتصرف- للمقال How to build your own Git server لصاحبه Seth Kenlon.

اقرأ أيضًا

تم التعديل في بواسطة رقية بورية


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...