
مقدمة
عند التطوير لنظام التشغيل linux ، هناك مهام لإنشاء نصوص تفاعلية يتم تنفيذها عند تشغيل النظام أو إيقاف تشغيله. في النظام الخامس ، تم ذلك بسهولة ، ولكن مع systemd فإنه يجعل التعديلات. ولكن يمكن أن تفعل توقيت لها.
لماذا نحتاج الهدف
غالبًا ما يتم كتابة هذا الهدف بمثابة تماثل لمستوى التشغيل في نظام V -init. أنا أختلف بشكل أساسي. هناك المزيد منها ويمكنك فصل الحزم في مجموعات ، على سبيل المثال ، تشغيل مجموعة من الخدمات مع فريق واحد وتنفيذ إجراءات إضافية. بالإضافة إلى ذلك ، ليس لديهم تسلسل هرمي ، بل تبعيات فقط.
مثال مستهدف عند بدء التشغيل (نظرة عامة على الميزة) مع إطلاق برنامج نصي تفاعلي
وصف الهدف نفسه:
cat installer.target [Unit] Description=My installer Requires=multi-user.target Conflicts=rescue.service rescue.target After=multi-user.target rescue.service rescue.target AllowIsolate=yes Wants=installer.service
سيبدأ هذا الهدف عندما يتم تشغيل multi-user.target ويقوم باستدعاء installer.service. علاوة على ذلك ، قد يكون هناك العديد من هذه الخدمات.
cat installer.service [Unit]
وأخيرًا ، مثال على برنامج نصي قابل للتنفيذ:
الشيء الأكثر أهمية هو اختيار final.target - الهدف ، والذي يجب أن يأتي إليه النظام عند بدء التشغيل. في عملية البدء ، سيستعرض systemd التبعيات ويقوم بتشغيل كل ما تحتاجه.
هناك عدة طرق لتحديد final.target ، لقد استخدمت خيار أداة تحميل التشغيل لهذا الغرض.
الإطلاق النهائي يشبه هذا:
- يبدأ محمل الإقلاع
- يقوم أداة تحميل التشغيل ببدء البرنامج الثابت بتمرير المعلمة final.target
- Systemd يبدأ بدء تشغيل النظام. ينتقل بالتتابع إلى installer.target أو work.target من basic.target من خلال تبعياتهم (على سبيل المثال ، multi -user.target). هذا الأخير ويؤدي النظام للعمل في الوضع المطلوب
إعداد البرامج الثابتة للإطلاق
عند إنشاء البرامج الثابتة ، هناك دائمًا مهمة لاستعادة حالة النظام عند بدء التشغيل وحفظه عند إيقاف التشغيل. الحالة تعني ملفات التكوين وملفات قاعدة البيانات وإعدادات الواجهة وما إلى ذلك.
Systemd تطلق العملية في هدف واحد بالتوازي. هناك تبعيات تسمح لك بتحديد تسلسل تنفيذ البرنامج النصي.
كيف يعمل في مشروعي ( https://habr.com/en/post/477008/ https://github.com/skif-web/monitor )
- يبدأ النظام
- تبدأ خدمة settings_restore.service ، وهي تتحقق من ملف settings.txt في قسم البيانات. إذا لم يكن هناك ، فسيتم وضع الملف المرجعي في مكانه ، ثم تتم استعادة إعدادات النظام:
- كلمة مرور المسؤول
- اسم المضيف،
- المنطقة الزمنية
- مكان
- يحدد ما إذا كانت جميع الوسائط قيد الاستخدام. افتراضيًا ، يكون حجم الصورة صغيرًا - لراحة النسخ والتسجيل في الوسائط. عند بدء التشغيل ، يتم التحقق مما إذا كان لا يزال هناك مساحة غير مستخدمة. إذا كان هناك - يتم إعادة تقسيم القرص.
- توليد معرف الجهاز من عنوان MAC. هذا مهم للحصول على نفس العنوان عبر DHCP.
- إعدادات الشبكة
- حجم السجل محدود
- إعداد محرك الأقراص الخارجي للعمل (في حالة تمكين الخيار المقابل وكان محرك الأقراص جديدًا)
- تشغيل postgresq
- تبدأ خدمة الاستعادة. هناك حاجة لإعداد zabbix نفسه وقاعدة البيانات الخاصة به:
- يتحقق إذا كان هناك بالفعل قاعدة بيانات zabbix. إذا لم يكن كذلك ، يتم إنشاؤه من تهيئة مقالب (يتم توفيرها مع zabbix)
- يتم إنشاء قائمة المناطق الزمنية (اللازمة لعرضها في واجهة الويب)
- تم العثور على IP الحالي ، يتم عرضه في القضية (دعوة لدخول وحدة التحكم)
- تتغير الدعوة - تظهر العبارة جاهزة للعمل
- البرامج الثابتة مستعدة للذهاب.
ملفات الخدمة مهمة ، فهي التي تحدد التسلسل لإطلاقها
[Unit] Description=restore system settings Before=network.service prepare.service postgresql.service systemd-networkd.service systemd-resolved.service [Service] Type=oneshot ExecStart=/usr/bin/settings_restore.sh [Install] WantedBy=multi-user.target
كما ترون ، قمت بعمل التبعيات حتى أقوم بتشغيل البرنامج النصي الخاص بي أولاً ، وعندها فقط سترتفع الشبكة وسيبدأ تشغيل نظام إدارة قواعد البيانات.
والخدمة الثانية (تحضير zabbix)
هذا الأمر أكثر تعقيدًا ، حيث يتم الإطلاق أيضًا في multi-user.target ، ولكن بعد تشغيل DBMS postgresql و setting_restore الخاص بي. ولكن قبل تشغيل خدمات zabbix.
الخدمة مع جهاز توقيت ل logrotate
Systemd يمكن أن تحل محل CRON. على محمل الجد. علاوة على ذلك ، لا تصل الدقة إلى دقيقة واحدة ، بل تصل إلى ثانية (ما إذا كانت هناك حاجة لذلك) ، ويمكنك إنشاء جهاز توقيت رتيب ، يطلق عليه مهلة من الحدث.
كان الموقت الرتيب الذي يحسب الوقت من بداية الجهاز الذي قمت بإنشائه.
هذا سوف يتطلب 2 الملفات
logrotateTimer.service - الوصف الفعلي للخدمة:
[Unit] Description=run logrotate [Service] ExecStart=logrotate /etc/logrotate.conf TimeoutSec=300
الأمر بسيط - وصف لأمر الإطلاق
الملف logrotateTimer.timer الثاني هو الذي يحدد مؤقتات العمل:
[Unit] Description=Run logrotate [Timer] OnBootSec=15min OnUnitActiveSec=15min [Install] WantedBy=timers.target
ما هو هناك:
- وصف الموقت
- أول مرة تبدأ من نظام التمهيد
- فترة من مزيد من الاطلاق
- اعتماد خدمة الموقت. في الواقع ، هذا هو الخط ويجعل الموقت
النصي التفاعلي على الاغلاق وهدف الاغلاق المخصص
في تطور آخر ، كان علي عمل نسخة أكثر تعقيدًا من إيقاف تشغيل الجهاز - من خلال هدفي الخاص ، من أجل القيام بالعديد من الإجراءات. يوصى عادةً بإنشاء خدمة oneshot باستخدام خيار RemainAfterExit ، لكن هذا يمنع إنشاء برنامج نصي تفاعلي.
ولكن الحقيقة هي أن الأوامر التي أطلقها خيار ExecOnStop يتم تنفيذها خارج TTY! الاختيار بسيط - أدخل الأمر tty واحفظ ناتجه.
لذلك ، قمت بتنفيذ الاغلاق من خلال هدفي. أنا لا أدعي أن تكون صحيحة بنسبة 100 ٪ ، لكنه يعمل!
كيف تم ذلك (بعبارات عامة):
أنشئ الهدف my_shutdown.target ، والذي لم يعتمد على أي شخص:
my_shutdown.target
[Unit] Description=my shutdown AllowIsolate=yes Wants=my_shutdown.service
عند التبديل إلى هذا الهدف (عبر systemctl عزل my_shutdwn.target) ، أطلق خدمة my_shutdown.service ، ومهمتها بسيطة - لتنفيذ البرنامج النصي my_shutdown.sh:
[Unit] Description=MY shutdown [Service] Type=oneshot ExecStart=/usr/bin/my_shutdown.sh StandardInput=tty TTYPath=/dev/tty3 TTYReset=yes TTYVHangup=yes WantedBy=my_shutdown.target
- داخل هذا البرنامج النصي ، أقوم بالإجراءات اللازمة. يمكنك إضافة الكثير من البرامج النصية إلى الهدف ، من أجل المرونة والراحة:
my_shutdown.sh
المذكرة. باستخدام / tmp / reboot و / tmp / shutdown الملفات. لا يمكنك استدعاء الهدف مع المعلمات. يمكنك فقط الخدمة.
ولكني أستخدم الهدف من أجل الحصول على مرونة في العمل وتسلسل مضمون من الإجراءات.
ومع ذلك ، كان الشيء الأكثر إثارة للاهتمام في وقت لاحق. يجب إيقاف تشغيل الجهاز / إعادة تشغيله. وهناك 2 خيارات:
- استبدل إعادة التشغيل والإغلاق والأوامر الأخرى (لا تزال الارتباطات على systemctl) بالبرنامج النصي الخاص بك ، وفي داخل البرنامج النصي ، انتقل إلى my_shutdown.target. والبرامج النصية داخل الهدف ثم استدعاء systemctl مباشرة ، على سبيل المثال ، إعادة تشغيل systemctl
- أبسط ، لكنني لا أحب الخيار. في جميع الواجهات ، لا تستدعي إيقاف التشغيل / إعادة التشغيل / الآخرين ، ولكن يمكنك الاتصال مباشرة بالنظام الهدف الهدف عزل my_shutdown.target
اخترت الخيار الأول. في SYSTEMD ، إعادة التشغيل (مثل poweroff) هي الارتباطات على systemd.
ls -l /sbin/poweroff lrwxrwxrwx 1 root root 14 30 18:23 /sbin/poweroff -> /bin/systemctl
لذلك ، يمكن استبدالها بنصوصك الخاصة:
تمهيد