Skriptet dhe kohëmatësit e sistemuar, ndërveprues

Skriptet dhe kohëmatësit e sistemuar, ndërveprues

Paraqitje

Kur zhvillohet për Linux, lind detyra e krijimit të skripteve interaktive që ekzekutohen kur sistemi ndizet ose mbyllet. Në sistemin V kjo ishte e lehtë, por me systemd bën rregullime. Por mund të ketë kohëmatësit e vet.

Pse na duhen objektivat?

Shpesh shkruhet se objektivi shërben si një analog i nivelit të ekzekutimit në sistemin V-init. Në thelb nuk jam dakord. Ka më shumë prej tyre dhe ju mund të ndani paketat në grupe dhe, për shembull, të nisni një grup shërbimesh me një komandë dhe të kryeni veprime shtesë. Për më tepër, ata nuk kanë hierarki, por vetëm varësi.

Shembull i objektivit kur aktivizohet (përmbledhje e veçorive) me ekzekutimin e skriptit interaktiv

Përshkrimi i vetë objektivit:

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

Ky objektiv do të fillojë kur të hapet multi-user.target dhe të telefonojë installer.service. Sidoqoftë, mund të ketë disa shërbime të tilla.

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

Dhe së fundi, një shembull i skenarit që po ekzekutohet:

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

Gjëja më e rëndësishme është të zgjidhni final.target - objektivin në të cilin sistemi duhet të arrijë në fillimin. Gjatë procesit të fillimit, systemd do të kalojë varësitë dhe do të nisë gjithçka që i nevojitet.
Ka mënyra të ndryshme për të zgjedhur final.target, unë përdora opsionin loader për këtë.

Nisja përfundimtare duket kështu:

  1. Nis ngarkuesi
  2. Bootloader fillon lëshimin e firmuerit duke kaluar parametrin final.target
  3. Systemd fillon të nisë sistemin. Në mënyrë sekuenciale shkon te installer.target ose work.target nga basic.target përmes varësive të tyre (për shembull, multi-user.target). Këto të fundit e sjellin sistemin të funksionojë në modalitetin e dëshiruar

Përgatitja e firmuerit për nisje

Kur krijoni firmware, gjithmonë lind detyra për të rivendosur gjendjen e sistemit në fillim dhe për ta ruajtur atë kur mbyllet. Gjendja nënkupton skedarët e konfigurimit, depozitat e bazës së të dhënave, cilësimet e ndërfaqes, etj.

Systemd drejton proceset në të njëjtin objektiv paralelisht. Ka varësi që ju lejojnë të përcaktoni sekuencën e fillimit të skripteve.

Si funksionon në projektin tim ( https://habr.com/ru/post/477008/ https://github.com/skif-web/monitor)

  1. Sistemi fillon
  2. Nis shërbimi settings_restore.service, i cili kontrollon praninë e skedarit settings.txt në seksionin e të dhënave. Nëse nuk është aty, atëherë në vend të tij vendoset një skedar referimi. Më pas, rikthehen cilësimet e sistemit:
    • fjalëkalimi i administratorit
    • emri i hostit,
    • zonë kohore
    • vendor
    • Përcakton nëse të gjitha mediat janë duke u përdorur. Si parazgjedhje, madhësia e imazhit është e vogël - për lehtësinë e kopjimit dhe regjistrimit në media. Në fillim, kontrollon nëse ka ende hapësirë ​​të papërdorur. Nëse ka, disku ndahet sërish.
    • Gjenerimi i identifikimit të makinës nga adresa MAC. Kjo është e rëndësishme për marrjen e të njëjtës adresë përmes DHCP
    • Cilësimet e rrjetit
    • Kufizon madhësinë e shkrimeve
    • Disku i jashtëm po përgatitet për punë (nëse opsioni përkatës është i aktivizuar dhe disku është i ri)
  3. Filloni postgresq
  4. Fillon shërbimi i rivendosjes. Është e nevojshme për të përgatitur vetë zabbix dhe bazën e të dhënave të tij:
    • Kontrollon nëse ekziston tashmë një bazë të dhënash zabbix. Nëse jo, ai krijohet nga deponitë e inicializimit (përfshirë me zabbix)
    • krijohet një listë e zonave kohore (të nevojshme për t'i shfaqur ato në ndërfaqen e internetit)
    • IP-ja aktuale është gjetur, shfaqet në problem (ftesë për t'u identifikuar në tastierë)
  5. Ftesa ndryshon - shfaqet fraza Gati për të punuar
  6. Firmware është gati për përdorim

Skedarët e shërbimit janë të rëndësishëm, janë ata që vendosin sekuencën e nisjes së tyre

[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

Siç mund ta shihni, unë instalova varësi në mënyrë që skripti im të funksiononte fillimisht, dhe vetëm atëherë rrjeti do të ngrihej dhe do të fillonte DBMS.

Dhe shërbimi i dytë (përgatitja e zabbix)

#!/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

Është pak më e komplikuar këtu. Nisja është gjithashtu në multi-user.target, por PAS nisjes së postgresql DBMS dhe setting_restore tim. Por PARA fillimit të shërbimeve zabbix.

Shërbimi i kohëmatësit për logrotate

Systemd mund të zëvendësojë CRON. Seriozisht. Për më tepër, saktësia nuk është deri në minutë, por deri në sekondë (po nëse është e nevojshme).Ose mund të krijoni një kohëmatës monoton, të thirrur nga një kohëzgjatje nga një ngjarje.
Ishte kohëmatësi monoton që numëron kohën nga fillimi i makinës që krijova.
Kjo do të kërkojë 2 skedarë
logrotateTimer.service - përshkrimi aktual i shërbimit:

[Unit]
Description=run logrotate

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

Është e thjeshtë - përshkrimi i komandës së nisjes.
Skedari i dytë logrotateTimer.timer është vendi ku funksionojnë kohëmatësit:

[Unit]
Description=Run logrotate

[Timer]
OnBootSec=15min
OnUnitActiveSec=15min

[Install]
WantedBy=timers.target

Çfarë ka këtu:

  • përshkrimi i kohëmatësit
  • Koha e parë e fillimit, duke filluar nga nisja e sistemit
  • periudha e nisjeve të mëtejshme
  • Varësia nga shërbimi i kohëmatësit.Në fakt, ky është vargu që bën kohëmatësin

Skript interaktiv kur mbyllet dhe objektivi juaj i mbylljes

Në një zhvillim tjetër, më duhej të bëja një version më kompleks të fikjes së makinës - përmes objektivit tim, në mënyrë që të kryeja shumë veprime. Zakonisht rekomandohet të krijoni një shërbim oneshot me opsionin RemainAfterExit, por kjo ju pengon të krijoni një skript interaktiv.

Por fakti është se komandat e lëshuara nga opsioni ExecOnStop ekzekutohen jashtë TTY! Është e lehtë për t'u kontrolluar - ngjitni komandën tty dhe ruani daljen e saj.

Prandaj, unë zbatova mbylljen përmes objektivit tim. Unë nuk pretendoj se jam 100% i saktë, por funksionon!
Si u bë (në terma të përgjithshëm):
Kam krijuar një objektiv my_shutdown.target, i cili nuk varej nga askush:
my_shutdown.objektiv

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

Kur shkon te ky objektiv (nëpërmjet systemctl izoluar my_shutdwn.target), ai nisi shërbimin my_shutdown.service, detyra e të cilit është e thjeshtë - të ekzekutojë skriptin 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

  • Brenda këtij skenari kryej veprimet e nevojshme. Ju mund të shtoni shumë skripta në objektiv për fleksibilitet dhe komoditet:

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

Shënim. Duke përdorur skedarët /tmp/reboot dhe /tmp/shutdown. Nuk mund të telefononi objektivin me parametra. Vetëm shërbimi është i mundur.

Por unë përdor objektivin për të pasur fleksibilitet në punë dhe një renditje të garantuar veprimesh.

Megjithatë, gjëja më interesante erdhi më vonë. Makina duhet të fiket/rifillohet. Dhe ka 2 opsione:

  • Zëvendësoni reboot, shutdown dhe komanda të tjera (ato janë ende simlink për systemctl) me skriptin tuaj. Brenda skriptit, shkoni te my_shutdown.target. Dhe skriptet brenda objektivit më pas thërrasin systemctl direkt, për shembull, systemctl reboot
  • Një opsion më i thjeshtë, por nuk më pëlqen. Në të gjitha ndërfaqet, mos telefononi shutdown/reboot/other, por thirrni drejtpërdrejt sistemin e synuarctl izoluar my_shutdown.target

Zgjodha opsionin e parë. Në systemd, reboot (si poweroff) janë lidhje simbolike me systemd.

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

Prandaj, ju mund t'i zëvendësoni ato me skriptet tuaja:
reboot

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

Burimi: www.habr.com

Shto një koment