Tizimli, interaktiv skriptlar va taymerlar

Tizimli, interaktiv skriptlar va taymerlar

kirish

Linux uchun ishlab chiqilayotganda, tizim yoqilganda yoki o'chirilganda bajariladigan interaktiv skriptlarni yaratish vazifasi paydo bo'ladi. V tizimida bu oson edi, lekin systemd bilan u sozlashlarni amalga oshiradi. Ammo uning o'z taymerlari bo'lishi mumkin.

Nega bizga maqsadlar kerak?

Ko'pincha maqsad V -init tizimida ishlash darajasining analogi bo'lib xizmat qiladi, deb yoziladi. Men tubdan rozi emasman. Ularning ko'pi bor va siz paketlarni guruhlarga bo'lishingiz va, masalan, bitta buyruq bilan xizmatlar guruhini ishga tushirishingiz va qo'shimcha harakatlar qilishingiz mumkin. Bundan tashqari, ularda ierarxiya yo'q, faqat bog'liqliklar mavjud.

Ishlayotgan interaktiv skript bilan yoqilganda maqsad misoli (xususiyatlar haqida umumiy ma'lumot).

Maqsadning o'zi tavsifi:

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

Bu maqsad multi-user.target ishga tushirilganda va installer.service ga qo'ng'iroq qilganda boshlanadi. Biroq, bir nechta bunday xizmatlar bo'lishi mumkin.

cat installer.service
[Unit]
# описание
Description=installer interactive dialog

[Service]
# Запустить один раз, когда остальное будет запущенно
Type=idle
# Команда запуска - вызов скрипта
ExecStart=/usr/bin/installer.sh
# Интерактивное взаимодействие с пользователем через tty3
StandardInput=tty
TTYPath=/dev/tty3
TTYReset=yes
TTYVHangup=yes

[Install]
WantedBy=installer.target

Va nihoyat, bajarilayotgan skriptga misol:

#!/bin/bash
# Переходим в tty3
chvt 3
echo "Install, y/n ?"
read user_answer

Eng muhimi, final.target-ni tanlash - tizim ishga tushganda erishish kerak bo'lgan maqsad. Ishga tushirish jarayonida systemd bog'liqliklardan o'tadi va kerak bo'lgan hamma narsani ishga tushiradi.
Final.target ni tanlashning turli usullari mavjud, men buning uchun yuklovchi variantidan foydalandim.

Yakuniy ishga tushirish quyidagicha ko'rinadi:

  1. Bootloader ishga tushadi
  2. Yuklash moslamasi final.target parametrini o'tkazish orqali mikrodasturni ishga tushirishni boshlaydi
  3. Systemd tizimni ishga tushirishni boshlaydi. O'z bog'liqliklari (masalan, multi-user.target) orqali basic.target dan installer.target yoki work.target ga ketma-ket o'tadi. Ikkinchisi tizimni kerakli rejimda ishlashga olib keladi

Mikrodasturni ishga tushirishga tayyorlash

Mikrodasturni yaratishda har doim ishga tushirilganda tizim holatini tiklash va o'chirishda uni saqlash vazifasi paydo bo'ladi. Holat konfiguratsiya fayllari, ma'lumotlar bazasi omborlari, interfeys sozlamalari va boshqalarni anglatadi.

Systemd bir xil maqsaddagi jarayonlarni parallel ravishda boshqaradi. Skriptlarni ishga tushirish ketma-ketligini aniqlashga imkon beruvchi bog'liqliklar mavjud.

Bu mening loyihamda qanday ishlaydi ( https://habr.com/ru/post/477008/ https://github.com/skif-web/monitor)

  1. Tizim boshlanadi
  2. settings_restore.service xizmati ishga tushirildi.U ma'lumotlar bo'limida settings.txt fayli mavjudligini tekshiradi. Agar u yo'q bo'lsa, uning o'rniga mos yozuvlar fayli joylashtiriladi, keyin tizim sozlamalari tiklanadi:
    • administrator paroli
    • xost nomi,
    • vaqt zonasi
    • mahalliy
    • Barcha ommaviy axborot vositalaridan foydalanilayotganligini aniqlaydi. Odatiy bo'lib, tasvir hajmi kichik - nusxa ko'chirish va mediaga yozib olish qulayligi uchun. Ishga tushganda, u hali ham foydalanilmagan bo'sh joy mavjudligini tekshiradi. Agar mavjud bo'lsa, disk qayta bo'linadi.
    • MAC manzilidan mashina identifikatori yaratilmoqda. Bu DHCP orqali bir xil manzilni olish uchun muhim
    • Tarmoq sozlamalari
    • Jurnallar hajmini cheklaydi
    • Tashqi disk ishlashga tayyorlanmoqda (agar mos variant yoqilgan bo'lsa va haydovchi yangi bo'lsa)
  3. Postgresq-ni boshlang
  4. Qayta tiklash xizmati boshlanadi. Zabbixning o'zini va uning ma'lumotlar bazasini tayyorlash uchun kerak:
    • Zabbix ma'lumotlar bazasi allaqachon mavjudligini tekshiradi. Agar yo'q bo'lsa, u ishga tushirish dumplaridan yaratilgan (zabbix bilan birga)
    • vaqt zonalari ro'yxati yaratiladi (ularni veb-interfeysda ko'rsatish uchun kerak)
    • Joriy IP topildi, u muammoda ko'rsatiladi (konsolga kirish uchun taklif)
  5. Taklifnoma o'zgaradi - Ishga tayyor iborasi paydo bo'ladi
  6. Mikrodastur foydalanishga tayyor

Xizmat fayllari muhim, ular ishga tushirish ketma-ketligini belgilaydiganlardir

[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

Ko'rib turganingizdek, men bog'liqliklarni o'rnatdim, shunda mening skriptim birinchi navbatda ishlaydi va shundan keyingina tarmoq ko'tariladi va DBMS ishga tushadi.

Va ikkinchi xizmat (zabbix tayyorlash)

#!/bin/sh
[Unit]
Description=monitor prepare system
After=postgresql.service settings_restore.service
Before=zabbix-server.service zabbix-agent.service

[Service]
Type=oneshot
ExecStart=/usr/bin/prepare.sh

[Install]
WantedBy=multi-user.target

Bu erda biroz murakkabroq.Ishga tushirish multi-user.target-da ham amalga oshiriladi, lekin postgresql DBMS va mening settings_restore ishga tushirilgandan keyin. Lekin zabbix xizmatlarini ishga tushirishdan oldin.

Logrotate uchun taymer xizmati

Systemd CRON o'rnini bosishi mumkin. Jiddiy. Bundan tashqari, aniqlik daqiqagacha emas, balki soniyagacha (agar kerak bo'lsa nima bo'ladi) Yoki siz hodisadan taym-aut bilan chaqiriladigan monoton taymerni yaratishingiz mumkin.
Bu men yaratgan mashinaning boshlanishidan vaqtni hisoblaydigan monoton taymer edi.
Buning uchun 2 ta fayl kerak bo'ladi
logrotateTimer.service - xizmatning haqiqiy tavsifi:

[Unit]
Description=run logrotate

[Service]
ExecStart=logrotate /etc/logrotate.conf
TimeoutSec=300

Bu oddiy - ishga tushirish buyrug'ining tavsifi.
LogrotateTimer.timer ikkinchi faylida taymerlar ishlaydi:

[Unit]
Description=Run logrotate

[Timer]
OnBootSec=15min
OnUnitActiveSec=15min

[Install]
WantedBy=timers.target

Bu yerda nima bor:

  • taymer tavsifi
  • Birinchi ishga tushirish vaqti, tizimni yuklashdan boshlab
  • keyingi ishga tushirish davri
  • Taymer xizmatiga bog'liqlik.Aslida, bu taymerni yaratuvchi qatordir

O'chirish paytida interaktiv skript va o'chirish maqsadingiz

Yana bir ishlanmada men ko'p harakatlarni amalga oshirish uchun mashinani o'chirishning yanada murakkab versiyasini - o'z maqsadim orqali qilishim kerak edi. Odatda RemainAfterExit opsiyasi bilan bir martalik xizmat yaratish tavsiya etiladi, biroq bu interaktiv skript yaratishga to‘sqinlik qiladi.

Ammo haqiqat shundaki, ExecOnStop opsiyasi tomonidan ishga tushirilgan buyruqlar TTYdan tashqarida bajariladi! Tekshirish oson - tty buyrug'ini joylashtiring va uning chiqishini saqlang.

Shuning uchun men maqsadim orqali o'chirishni amalga oshirdim. Men 100% to'g'ri deb da'vo qilmayman, lekin u ishlaydi!
Bu qanday amalga oshirildi (umumiy ma'noda):
Hech kimga bog'liq bo'lmagan my_shutdown.target nishonini yaratdim:
my_shutdown.target

[Unit]
Description=my shutdown
AllowIsolate=yes
Wants=my_shutdown.service 

Ushbu maqsadga o'tishda (systemctl isolate my_shutdwn.target orqali) u my_shutdown.service xizmatini ishga tushirdi, uning vazifasi oddiy - my_shutdown.sh skriptini bajarish:

[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

  • Ushbu skript ichida men kerakli harakatlarni bajaraman. Moslashuvchanlik va qulaylik uchun maqsadga ko'plab skriptlarni qo'shishingiz mumkin:

my_shutdown.sh

#!/bin/bash --login
if [ -f /tmp/reboot ];then
    command="systemctl reboot"
elif [ -f /tmp/shutdown ]; then
    command="systemctl poweroff"
fi
#Вот здесь нужные команды
#Например, cp /home/user/data.txt /storage/user/
    $command

Eslatma. /tmp/reboot va /tmp/shutdown fayllaridan foydalanish. Parametrlar bilan maqsadni chaqira olmaysiz. Faqat xizmat ko'rsatish mumkin.

Lekin men ishda moslashuvchanlik va kafolatlangan harakatlar tartibiga ega bo'lish uchun maqsaddan foydalanaman.

Biroq, eng qiziqarli narsa keyinroq paydo bo'ldi. Mashinani o'chirish/qayta ishga tushirish kerak. Va ikkita variant mavjud:

  • Qayta yuklash, o'chirish va boshqa buyruqlarni (ular hali ham systemctl ga simli havolalar) o'z skriptingiz bilan almashtiring.Skript ichida my_shutdown.target saytiga o'ting. Va maqsad ichidagi skriptlar to'g'ridan-to'g'ri systemctl ni chaqiradi, masalan, systemctl reboot
  • Oddiyroq variant, lekin menga yoqmaydi. Barcha interfeyslarda shutdown/reboot/other deb chaqirmang, lekin to'g'ridan-to'g'ri maqsadli systemctl isolate my_shutdown.target-ga qo'ng'iroq qiling.

Men birinchi variantni tanladim. Systemd-da qayta ishga tushirish (masalan, quvvatni o'chirish) systemd-ga simli havolalardir.

ls -l /sbin/poweroff 
lrwxrwxrwx 1 root root 14 сен 30 18:23 /sbin/poweroff -> /bin/systemctl

Shuning uchun siz ularni o'zingizning skriptlaringiz bilan almashtirishingiz mumkin:
qayta ishga tushirish

#!/bin/sh
    touch /tmp/reboot
    sudo systemctl isolate my_shutdown.target
fi

Manba: www.habr.com

a Izoh qo'shish