Sissejuhatus
Linuxi jaoks arendades tekib interaktiivsete skriptide loomise ülesanne, mis käivitatakse süsteemi sisse- või väljalülitamisel. Süsteemis V oli see lihtne, kuid systemd puhul teeb see kohandusi. Kuid sellel võivad olla oma taimerid.
Miks me vajame sihtmärke?
Sageli kirjutatakse, et siht toimib süsteemi V -init käitustaseme analoogina. Ma ei ole põhimõtteliselt nõus. Neid on rohkem ja saab pakette gruppideks jagada ning näiteks ühe käsuga teenuste grupi käivitada ja lisatoiminguid teha. Pealegi pole neil hierarhiat, on vaid sõltuvused.
Näide sihtmärgist, kui see on lubatud (funktsiooni ülevaade) koos töötava interaktiivse skriptiga
Sihtmärgi enda kirjeldus:
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
See sihtmärk käivitub, kui multi-user.target käivitatakse ja kutsub esile installer.service. Selliseid teenuseid võib siiski olla mitu.
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
Ja lõpuks näide käivitatavast skriptist:
#!/bin/bash
# Переходим в tty3
chvt 3
echo "Install, y/n ?"
read user_answer
Kõige olulisem on valida final.target – sihtmärk, milleni süsteem käivitamisel jõudma peaks. Käivitusprotsessi ajal läbib systemd sõltuvused ja käivitab kõik vajaliku.
Final.target valimiseks on erinevaid viise, mina kasutasin selleks laaduri valikut.
Lõplik käivitamine näeb välja selline:
- Alglaadur käivitub
- Alglaadur alustab püsivara käivitamist, edastades parameetri final.target
- Systemd alustab süsteemi käivitamist. Suunab failist basic.target järjestikku installer.target või work.target nende sõltuvuste kaudu (nt multi-user.target). Viimased panevad süsteemi soovitud režiimis tööle
Püsivara ettevalmistamine käivitamiseks
Püsivara loomisel tekib alati ülesanne süsteemi oleku taastamine käivitamisel ja salvestamine väljalülitamisel. Olek tähendab konfiguratsioonifaile, andmebaasi tõmmiseid, liidese sätteid jne.
Systemd käitab protsesse samas sihtmärgis paralleelselt. On sõltuvusi, mis võimaldavad teil määrata skriptide käivitusjärjestuse.
Kuidas see minu projektis töötab (
- Süsteem käivitub
- Käivitatakse teenus settings_restore.service, mis kontrollib andmejaotises faili settings.txt olemasolu. Kui seda pole, asetatakse selle asemele viitefail. Järgmiseks taastatakse süsteemi sätted:
- administraatori parool
- hostinimi,
- ajavöönd
- lokaat
- Määrab, kas kogu meediat kasutatakse. Vaikimisi on pildi suurus väike – kopeerimise ja kandjale salvestamise hõlbustamiseks. Käivitamisel kontrollib see, kas on veel kasutamata ruumi. Kui see on olemas, jagatakse ketas ümber.
- Masina ID genereerimine MAC-aadressist. See on oluline sama aadressi saamiseks DHCP kaudu
- Võrgusätted
- Piirab palkide suurust
- Välist draivi valmistatakse tööks ette (kui vastav valik on lubatud ja draiv on uus)
- Alusta postgresq
- Taastamisteenus käivitub. See on vajalik zabbixi enda ja selle andmebaasi ettevalmistamiseks:
- Kontrollib, kas zabbixi andmebaas on juba olemas. Kui ei, siis luuakse see lähtestamisväljavõtetest (kaasas zabbixiga)
- luuakse ajavööndite loend (vajalik nende kuvamiseks veebiliideses)
- Praegune IP on leitud, see kuvatakse väljaandes (kutse konsooli sisse logida)
- Kutse muutub – ilmub fraas Tööks valmis
- Püsivara on kasutamiseks valmis
Teenusfailid on olulised, need määravad nende käivitamise järjekorra
[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
Nagu näete, installisin sõltuvused nii, et minu skript hakkaks kõigepealt tööle ja alles siis läheks võrk üles ja DBMS käivituks.
Ja teine teenus (zabbixi ettevalmistamine)
#!/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
Siin on see veidi keerulisem. Käivitamine toimub ka saidis multi-user.target, kuid PÄRAST postgresql DBMS-i ja minu setting_restore'i käivitamist. Aga ENNE zabbixi teenuste käivitamist.
Taimeri teenus logrotate jaoks
Systemd võib CRON-i asendada. Tõsiselt. Pealegi pole täpsus mitte minutini, vaid sekundini (mis siis, kui seda vaja läheb) Või saate luua monotoonse taimeri, mida kutsub sündmuse ajalõpp.
See oli monotoonne taimer, mis loeb aega minu loodud masina käivitamisest.
Selleks on vaja 2 faili
logrotateTimer.service – teenuse tegelik kirjeldus:
[Unit]
Description=run logrotate
[Service]
ExecStart=logrotate /etc/logrotate.conf
TimeoutSec=300
See on lihtne – käivituskäsu kirjeldus.
Teine fail logrotateTimer.timer on koht, kus taimerid töötavad:
[Unit]
Description=Run logrotate
[Timer]
OnBootSec=15min
OnUnitActiveSec=15min
[Install]
WantedBy=timers.target
Mis siin on:
- taimeri kirjeldus
- Esimene käivitusaeg, alates süsteemi alglaadimisest
- edasiste käivitamiste periood
- Sõltuvus taimeri teenusest. Tegelikult on see string, mis taimeri teeb
Interaktiivne skript väljalülitamisel ja teie sulgemise sihtmärk
Teises arenduses pidin paljude toimingute tegemiseks tegema keerukama versiooni masina väljalülitamisest - läbi enda sihtmärgi. Tavaliselt soovitatakse luua oneshot-teenus valikuga RemainAfterExit, kuid see takistab interaktiivse skripti loomist.
Kuid tõsiasi on see, et suvandi ExecOnStop käivitatud käsud täidetakse väljaspool TTY-d! Seda on lihtne kontrollida – kleepige käsk tty ja salvestage selle väljund.
Seetõttu rakendasin sulgemise oma eesmärgi kaudu. Ma ei väida, et mul on 100% õigus, kuid see töötab!
Kuidas seda tehti (üldiselt):
Lõin sihtmärgi my_shutdown.target, mis ei sõltunud kellestki:
my_shutdown.target
[Unit]
Description=my shutdown
AllowIsolate=yes
Wants=my_shutdown.service
Sellele sihtmärgile minnes (süsteemictl isolate my_shutdwn.target kaudu) käivitas see teenuse my_shutdown.service, mille ülesanne on lihtne - käivitada skript 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
- Selle skripti sees teen vajalikud toimingud. Paindlikkuse ja mugavuse huvides saate sihtmärgile lisada palju skripte.
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
Märge. Failide /tmp/reboot ja /tmp/shutdown kasutamine. Te ei saa sihtmärki parameetritega kutsuda. Võimalik on ainult teenindus.
Kuid kasutan eesmärki, et omada töös paindlikkust ja garanteeritud tegevuste järjekorda.
Kõige huvitavam tuli aga hiljem. Masin tuleb välja lülitada/taaskäivitada. Ja seal on 2 võimalust:
- Asendage taaskäivitamise, väljalülitamise ja muud käsud (need on endiselt systemctl-i sümbollingid) oma skriptiga. Minge skripti sees saidile my_shutdown.target. Ja sihtmärgi sees olevad skriptid kutsuvad siis systemctl otse, näiteks systemctl reboot
- Lihtsam variant, aga mulle ei meeldi. Kõigis liidestes ärge kutsuge välja shutdown/reboot/other, vaid kutsuge otse sihtmärk systemctl isolate my_shutdown.target
Valisin esimese variandi. Systemd-is on taaskäivitamine (nagu väljalülitamine) sümboliteks süsteemile.
ls -l /sbin/poweroff
lrwxrwxrwx 1 root root 14 сен 30 18:23 /sbin/poweroff -> /bin/systemctl
Seetõttu saate need asendada oma skriptidega:
reboot
#!/bin/sh
touch /tmp/reboot
sudo systemctl isolate my_shutdown.target
fi
Allikas: www.habr.com