Sistēmiski, interaktīvi skripti un taimeri

Sistēmiski, interaktīvi skripti un taimeri

Ievads

Izstrādājot Linux, rodas uzdevums izveidot interaktīvus skriptus, kas tiek izpildīti, kad sistēma tiek ieslēgta vai izslēgta. Sistēmā V tas bija viegli, bet ar systemd tas veic korekcijas. Bet tam var būt savi taimeri.

Kāpēc mums ir vajadzīgi mērķi?

Bieži tiek rakstīts, ka mērķis kalpo kā izpildes līmeņa analogs sistēmā V -init. Es principiāli nepiekrītu. To ir vairāk un jūs varat sadalīt pakotnes grupās un, piemēram, ar vienu komandu palaist pakalpojumu grupu un veikt papildu darbības. Turklāt viņiem nav hierarhijas, ir tikai atkarības.

Mērķa piemērs, kad tas ir iespējots (funkciju pārskats), izmantojot interaktīvu skriptu

Paša mērķa apraksts:

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

Šis mērķis tiks palaists, kad tiks palaists multi-user.target un izsauks installer.service. Tomēr šādi pakalpojumi var būt vairāki.

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

Un visbeidzot, izpildāmā skripta piemērs:

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

Vissvarīgākais ir izvēlēties final.target — mērķi, uz kuru sistēmai jānonāk startēšanas laikā. Startēšanas procesa laikā systemd veiks atkarības un palaidīs visu nepieciešamo.
Ir dažādi veidi, kā atlasīt final.target, šim nolūkam es izmantoju iekrāvēja opciju.

Pēdējā palaišana izskatās šādi:

  1. Sāk sāknēšanas ielādētājs
  2. Sāknēšanas ielādētājs sāk programmaparatūras palaišanu, nododot parametru final.target
  3. Systemd sāk startēt sistēmu. Secīgi pāriet uz installer.target vai work.target no basic.target, izmantojot to atkarības (piemēram, multi-user.target). Pēdējie nodrošina sistēmas darbību vēlamajā režīmā

Programmaparatūras sagatavošana palaišanai

Veidojot programmaparatūru, vienmēr rodas uzdevums atjaunot sistēmas stāvokli startēšanas laikā un saglabāt to izslēgšanas laikā. Stāvoklis nozīmē konfigurācijas failus, datu bāzes izgāztuves, interfeisa iestatījumus utt.

Systemd paralēli palaiž procesus tajā pašā mērķī. Ir atkarības, kas ļauj noteikt skriptu startēšanas secību.

Kā tas darbojas manā projektā ( https://habr.com/ru/post/477008/ https://github.com/skif-web/monitor)

  1. Sistēma sākas
  2. Tiek palaists pakalpojums settings_restore.service. Tas pārbauda, ​​vai datu sadaļā nav faila settings.txt. Ja tā nav, tad tā vietā tiek ievietots atsauces fails. Tālāk tiek atjaunoti sistēmas iestatījumi:
    • administratora parole
    • resursdatora nosaukums,
    • laika zona
    • lokalizācija
    • Nosaka, vai tiek izmantoti visi datu nesēji. Pēc noklusējuma attēla izmērs ir mazs — lai atvieglotu kopēšanu un ierakstīšanu datu nesējā. Startēšanas laikā tas pārbauda, ​​vai joprojām ir neizmantota vieta. Ja ir, disks tiek atkārtoti sadalīts.
    • Mašīnas ID ģenerēšana no MAC adreses. Tas ir svarīgi, lai iegūtu vienu un to pašu adresi, izmantojot DHCP
    • Tīkla iestatījumi
    • Ierobežo baļķu izmēru
    • Ārējais diskdzinis tiek sagatavots darbam (ja ir iespējota atbilstošā opcija un disks ir jauns)
  3. Sākt postgresq
  4. Sākas atjaunošanas pakalpojums. Tas ir nepieciešams, lai sagatavotu pašu zabbix un tā datu bāzi:
    • Pārbauda, ​​vai jau ir zabbix datu bāze. Ja nē, tas tiek izveidots no inicializācijas izgāztuvēm (iekļauts kopā ar zabbix)
    • tiek izveidots laika joslu saraksts (nepieciešams, lai tās parādītu tīmekļa saskarnē)
    • Pašreizējais IP ir atrasts, tas tiek parādīts izdevumā (aicinājums pieteikties konsolē)
  5. Uzaicinājums mainās – parādās frāze Gatavs darbam
  6. Programmaparatūra ir gatava lietošanai

Pakalpojuma faili ir svarīgi, tie ir tie, kas nosaka to palaišanas secību

[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

Kā redzat, es instalēju atkarības, lai mans skripts vispirms darbotos, un tikai pēc tam tīkls paceltos un sāktos DBVS.

Un otrais pakalpojums (zabbix sagatavošana)

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

Šeit ir nedaudz sarežģītāk. Palaišana notiek arī multi-user.target, bet PĒC postgresql DBVS un my setting_restore palaišanas. Bet PIRMS zabbix pakalpojumu uzsākšanas.

Taimera pakalpojums logrotate

Systemd var aizstāt CRON. Nopietni. Turklāt precizitāte ir nevis līdz minūtei, bet līdz sekundei (ja tā ir vajadzīga), vai arī varat izveidot monotonu taimeri, ko izsauc notikuma taimauts.
Tas bija monotonais taimeris, kas skaita laiku no manis izveidotās mašīnas palaišanas.
Tam būs nepieciešami 2 faili
logrotateTimer.service - faktiskais pakalpojuma apraksts:

[Unit]
Description=run logrotate

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

Tas ir vienkārši - palaišanas komandas apraksts.
Taimeri darbojas otrajā failā logrotateTimer.timer:

[Unit]
Description=Run logrotate

[Timer]
OnBootSec=15min
OnUnitActiveSec=15min

[Install]
WantedBy=timers.target

Kas šeit:

  • taimera apraksts
  • Pirmais starta laiks, sākot no sistēmas sāknēšanas
  • turpmāko palaišanas periods
  • Atkarība no taimera pakalpojuma. Patiesībā šī ir virkne, kas veido taimeri

Interaktīvs skripts izslēgšanas laikā un izslēgšanas mērķis

Citā izstrādē man bija jāveic sarežģītāka mašīnas izslēgšanas versija - caur savu mērķi, lai veiktu daudzas darbības. Parasti ir ieteicams izveidot oneshot pakalpojumu ar opciju RemainAfterExit, taču tas neļauj izveidot interaktīvu skriptu.

Bet fakts ir tāds, ka ExecOnStop opcijas palaistās komandas tiek izpildītas ārpus TTY! To ir viegli pārbaudīt - ielīmējiet komandu tty un saglabājiet tās izvadi.

Tāpēc es īstenoju izslēgšanu, izmantojot savu mērķi. Es neapgalvoju, ka man ir 100% taisnība, bet tas darbojas!
Kā tas tika darīts (vispārīgi):
Es izveidoju mērķi my_shutdown.target, kas nebija atkarīgs no neviena:
my_shutdown.target

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

Dodoties uz šo mērķi (izmantojot systemctl izolātu my_shutdwn.target), tika palaists pakalpojums my_shutdown.service, kura uzdevums ir vienkāršs - izpildīt my_shutdown.sh skriptu:

[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

  • Šajā skriptā es veicu nepieciešamās darbības. Mērķim varat pievienot daudzus skriptus, lai nodrošinātu elastību un ērtības:

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

Piezīme. Izmantojot /tmp/reboot un /tmp/shutdown failus. Jūs nevarat izsaukt mērķi ar parametriem. Iespējama tikai apkalpošana.

Bet es izmantoju mērķi, lai būtu elastība darbā un garantēta darbību secība.

Tomēr interesantākais notika vēlāk. Iekārta ir jāizslēdz/jārestartē. Un ir 2 iespējas:

  • Aizstājiet atsāknēšanas, izslēgšanas un citas komandas (tās joprojām ir simboliskās saites uz systemctl) ar savu skriptu. Skriptā atveriet vietni my_shutdown.target. Un mērķa iekšpusē esošie skripti pēc tam tieši izsauc systemctl, piemēram, systemctl atsāknēšana
  • Vienkāršāks variants, bet man tas nepatīk. Visās saskarnēs neizsauciet shutdown/reboot/other, bet tieši izsauciet mērķa systemctl izolate my_shutdown.target.

Es izvēlējos pirmo variantu. Sistēmā systemd atsāknēšana (piemēram, izslēgšana) ir simboliskās saites uz systemd.

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

Tāpēc varat tos aizstāt ar saviem skriptiem:
atsāknēšana

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

Avots: www.habr.com

Pievieno komentāru