Systemd, interaktivne skripte i mjerači vremena

Systemd, interaktivne skripte i mjerači vremena

Uvod

Prilikom razvoja za Linux javlja se zadatak stvaranja interaktivnih skripti koje se izvršavaju kada se sustav uključi ili isključi. U sustavu V to je bilo lako, ali sa systemd-om vrši prilagodbe. Ali može imati vlastite mjerače vremena.

Zašto su nam potrebni ciljevi?

Često se piše da target služi kao analog runlevel-a u sustavu V -init. U osnovi se ne slažem. Ima ih više i pakete možete podijeliti u grupe i npr. jednom naredbom pokrenuti grupu servisa i izvršiti dodatne radnje. Štoviše, nemaju hijerarhiju, samo ovisnosti.

Primjer cilja kada je omogućen (pregled značajki) s pokrenutom interaktivnom skriptom

Opis same mete:

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

Ovaj cilj će se pokrenuti kada se pokrene multi-user.target i pozove installer.service. Međutim, može biti nekoliko takvih usluga.

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

I na kraju, primjer skripte koja se izvršava:

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

Najvažnije je odabrati final.target - cilj do kojeg bi sustav trebao stići pri pokretanju. Tijekom procesa pokretanja, systemd će proći kroz ovisnosti i pokrenuti sve što treba.
Postoje različiti načini odabira final.target, za ovo sam koristio opciju učitavača.

Konačno lansiranje izgleda ovako:

  1. Pokreće se bootloader
  2. Bootloader počinje pokretati firmware prosljeđivanjem parametra final.target
  3. Systemd počinje pokretati sustav. Sekvencijalno ide na installer.target ili work.target od basic.target kroz njihove ovisnosti (na primjer, multi-user.target). Potonji dovode sustav u rad u željenom načinu rada

Priprema firmvera za pokretanje

Prilikom izrade firmvera uvijek se pojavljuje zadatak vraćanja stanja sustava pri pokretanju i njegovog spremanja pri gašenju. Stanje znači konfiguracijske datoteke, ispise baze podataka, postavke sučelja itd.

Systemd paralelno pokreće procese u istom cilju. Postoje ovisnosti koje vam omogućuju određivanje redoslijeda pokretanja skripti.

Kako to funkcionira u mom projektu ( https://habr.com/ru/post/477008/ https://github.com/skif-web/monitor)

  1. Sustav se pokreće
  2. Pokrenut je servis settings_restore.service koji provjerava prisutnost datoteke settings.txt u odjeljku podataka. Ako ga nema, tada se na njegovo mjesto postavlja referentna datoteka. Zatim se vraćaju postavke sustava:
    • administratorska lozinka
    • ime hosta,
    • Vremenska zona
    • lokalitet
    • Određuje koriste li se svi mediji. Prema zadanim postavkama, veličina slike je mala - radi lakšeg kopiranja i snimanja na medije. Prilikom pokretanja provjerava ima li još neiskorištenog prostora. Ako postoji, disk se ponovno particionira.
    • Generiranje id-a stroja iz MAC adrese. Ovo je važno za dobivanje iste adrese putem DHCP-a
    • Mrežne postavke
    • Ograničava veličinu trupaca
    • Eksterni disk se priprema za rad (ako je odgovarajuća opcija uključena i disk je nov)
  3. Pokrenite postgresq
  4. Pokreće se usluga vraćanja. Potrebno je pripremiti sam zabbix i njegovu bazu podataka:
    • Provjerava postoji li već zabbix baza podataka. Ako nije, kreira se iz inicijalizacijskih ispisa (uključeno u zabbix)
    • kreira se popis vremenskih zona (potreban za njihov prikaz u web sučelju)
    • Pronađen je trenutni IP, prikazan je u problemu (poziv za prijavu na konzolu)
  5. Pozivnica se mijenja - pojavljuje se izraz Ready to work
  6. Firmware je spreman za upotrebu

Servisne datoteke su važne, one postavljaju redoslijed njihovog pokretanja

[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

Kao što vidite, instalirao sam zavisnosti kako bi moja skripta prvo radila, a tek onda bi se mreža digla i DBMS pokrenuo.

I druga usluga (zabbix priprema)

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

Ovdje je malo kompliciranije. Pokretanje je također u multi-user.target, ali NAKON pokretanja postgresql DBMS-a i moje postavke_restore. Ali PRIJE pokretanja zabbix usluga.

Usluga mjerača vremena za logrotate

Systemd može zamijeniti CRON. Ozbiljno. Štoviše, točnost nije do minute, već do sekunde (što ako je potrebno).Ili možete stvoriti monotoni mjerač vremena, pozvan timeoutom od događaja.
Stvorio sam monotoni mjerač vremena koji broji vrijeme od pokretanja stroja.
Ovo će zahtijevati 2 datoteke
logrotateTimer.service - stvarni opis usluge:

[Unit]
Description=run logrotate

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

Jednostavno je - opis naredbe za pokretanje.
Druga datoteka logrotateTimer.timer je mjesto gdje mjerači vremena rade:

[Unit]
Description=Run logrotate

[Timer]
OnBootSec=15min
OnUnitActiveSec=15min

[Install]
WantedBy=timers.target

Što je ovdje:

  • opis mjerača vremena
  • Prvo vrijeme pokretanja, počevši od pokretanja sustava
  • razdoblje daljnjih lansiranja
  • Ovisnost o usluzi mjerača vremena. Zapravo, ovo je niz koji čini mjerač vremena

Interaktivna skripta prilikom isključivanja i vaš cilj isključivanja

U drugom razvoju, morao sam napraviti složeniju verziju isključivanja stroja - kroz vlastitu metu, kako bih izvršio mnoge radnje. Obično se preporučuje stvaranje oneshot usluge s opcijom RemainAfterExit, ali to vas sprječava u stvaranju interaktivne skripte.

Ali činjenica je da se naredbe koje pokreće ExecOnStop opcija izvršavaju izvan TTY-a! Lako je provjeriti - zalijepite naredbu tty i spremite njen izlaz.

Stoga sam implementirao gašenje putem svog cilja. Ne tvrdim da sam 100% točan, ali radi!
Kako je to učinjeno (općenito):
Stvorio sam cilj my_shutdown.target, koji nije ovisio ni o kome:
moje_gašenje.cilj

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

Pri odlasku na ovaj cilj (putem systemctl isolate my_shutdwn.target), pokrenuo je uslugu my_shutdown.service, čiji je zadatak jednostavan - izvršiti skriptu 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

  • Unutar ove skripte izvodim potrebne radnje. Možete dodati mnoge skripte cilju za fleksibilnost i praktičnost:

moje_gašenje.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

Bilješka. Korištenje datoteka /tmp/reboot i /tmp/shutdown. Ne možete pozvati cilj s parametrima. Moguć samo servis.

Ali koristim target kako bih imao fleksibilnost u radu i zajamčen redoslijed radnji.

Ipak, ono najzanimljivije došlo je kasnije. Stroj je potrebno isključiti/ponovno pokrenuti. A postoje 2 opcije:

  • Zamijenite reboot, shutdown i druge naredbe (one su još uvijek simboličke veze na systemctl) svojom skriptom. Unutar skripte idite na my_shutdown.target. A skripte unutar cilja tada izravno pozivaju systemctl, na primjer, systemctl reboot
  • Jednostavnija opcija, ali mi se ne sviđa. U svim sučeljima nemojte pozivati ​​shutdown/reboot/other, već izravno pozivajte ciljni systemctl isolate my_shutdown.target

Odabrao sam prvu opciju. U systemd-u, ponovno pokretanje (poput isključivanja) su simboličke veze na systemd.

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

Stoga ih možete zamijeniti vlastitim skriptama:
ponovno

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

Izvor: www.habr.com

Dodajte komentar