
Hyrje
Kur ndihmohet me Linux, shpesh shfaqen detyra për të krijuar skripta interaktive që ekzekutohen në ndezje ose në mbyllje të sistemit. Me SystemV kjo ishte e lehtë, por me Systemd ka disa ndryshime. Mirëpo, ai ka gjithashtu timerat e tij.
Pse duhen target
Shpesh thuhet se target-i shërben si një ekuivalent për runlevel në System V - init. Unë nuk e kam në tërësi atë mendim. Ata janë më shumë dhe mund të ndahen paketat në grupe dhe, për shembull, të startojnë një grup shërbimesh me një komandë, të kryejnë veprime të tjera. Për më tepër, ata nuk kanë hieraki, vetëm varësi.
Shembulli i target në ndezje (përmbledhje e mundësive) me startimin e një skripti interaktiv
Përshkrimi i vetë target:
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.serviceKy target do të startohet kur të startohet multi-user.target dhe do të thërrasë installer.service. Në këtë rast, mund të ketë disa shërbime të tilla.
cat installer.service
[Unit]
# përshkrimi
Description=installer interactive dialog
[Service]
# Startohet një herë, kur të startohet e gjithë pjesa tjetër
Type=idle
# Komanda e startit - thirrja e skriptit
ExecStart=/usr/bin/installer.sh
# Interaksioni interaktiv me përdoruesin përmes tty3
StandardInput=tty
TTYPath=/dev/tty3
TTYReset=yes
TTYVHangup=yes
[Install]
WantedBy=installer.targetDhe për fund, shembulli i skriptit të ekzekutuar:
#!/bin/bash
# ĐĐ”ŃĐ”Ń
ĐŸĐŽĐžĐŒ ĐČ tty3
chvt 3
echo "Install, y/n ?"
read user_answerE rëndësishme është të zgjidhet final.target - target-i në të cilin sistemi duhet të arrijë gjatë ndezjes. Në procesin e ndezjes, systemd do të kalojë përmes varësive dhe do të startojë gjithçka që nevojitet.
Mund të zgjidhet final.target në mënyra të ndryshme, unë përdora opsionin e bootloader-it për këtë.
Ndezja përfundimtare duket kështu:
- Bootloader-i starton
- Bootloader-i fillon startimin e firmware, duke kaluar parametrin final.target
- Systemd fillon të startojë sistemin. Rregullisht shkon kah installer.target ose work.target nga basic.target përmes varësive të tyre (p.sh., multi-user.target). Këto të fundit e sjellin sistemin në funksion në mënyrën e duhur
Përgatitja e firmware për ndezje
Kur krijoni firmware gjithmonë shfaqet detyra e rikthimit të gjendjes së sistemit gjatë startit dhe ruajtjes së tij gjatë mbylljes. Nga gjendja nënkuptohet skedarët e konfigurimit, dump-et e bazës së të dhënave, konfigurimet e ndërfaqeve etj.
Systemd starton proceset në një target paralelisht. Ka varësi që lejojnë përcaktimin e rendit të ekzekutimit të skripteve.
Si funksionon kjo në projektin tim ( )
- Sistemi starton
- Startohet shërbimi settings_restore.service. Ai kontrollon nëse skedari settings.txt ekziston në seksionin e të dhënave. Nëse nuk ekziston, vendoset një skedar standard në vend të tij. Më pas ndodh rikthimi i konfigurimeve të sistemit:
- fjalëkalimi i administratorit
- hostname,
- zonën e kohës
- lokalen
- PĂ«rcaktimi nĂ«se Ă«shtĂ« pĂ«rdoresh nga e gjithĂ« masa. NĂ« mĂ«nyrĂ« standarde, madhĂ«sia e imazhit Ă«shtĂ« e vogĂ«l â pĂ«r lehtĂ«sinĂ« e kopjimit dhe shkrimit nĂ« medium. GjatĂ« startit kontrollohet â nĂ«se ka ende hapĂ«sirĂ« tĂ« papĂ«rdorur. NĂ«se ka â disku ribashkohet.
- Gjenerimi i machine-id nga MAC-adresa. Kjo është e rëndësishme për marrjen e të njëjtit adresë përmes DHCP
- Konfigurimet e rrjetit
- Kufizohet madhësia e log-eve
- Përgatitet disku i jashtëm (nëse është aktivizuar opsioni dhe disku është i ri)
- Startohet postgresq
- startohet shërbimi restore. Ai është i nevojshëm për përgatitjen e vetë zabbix dhe bazës së të dhënave të tij:
- Kontrollohet nĂ«se ekziston tashmĂ« baza e tĂ« dhĂ«nave zabbix. NĂ«se nuk ka â krijohet nga dump-et iniciale (vijnĂ« me zabbix-in)
- krijohet një listë e zonave kohore (nevojitet për t'i paraqitur ato në ndërfaqen web)
- Gjendet IP aktual, e cila shfaqet në issue (fllan për hyrje në konsolë)
- ShkĂ«putet fllanja â shfaqet fraza Ready to work
- Firmware është gati për punë
Skedarët e shërbimeve janë të rëndësishëm, ata vendosin rendin e startit të 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.targetSiç duket, kam vendosur varësi që skripti im të funksionojë së pari, dhe vetëm më pas të startohet rrjeti dhe SGBD.
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.targetKëtu është pak më e ndërlikuar. Starti gjithashtu ndodh në multi-user.target, por PAS startit të SGBD postgresql dhe settings_restore tim. Por PARA startit të shërbimeve zabbix.
Shërbimi me timer për logrotate
Systemd mund të zëvendësojë CRON. Me të vërtetë. Dhe saktësia është jo deri në minutë, por deri në sekondë (nëse do nevojitet). Gjithashtu, mund të krijohet një timer monotone, e cila thirret me timeout nga një ngjarje.
Pikërisht këtë timer monotone, i cili llogarit kohën nga ndezja e makinës, e krijova.
Për këtë do të nevojiten 2 skedare
logrotateTimer.service â pĂ«rshkrimi i shĂ«rbimit:
[Unit]
Description=run logrotate
[Service]
ExecStart=logrotate /etc/logrotate.conf
TimeoutSec=300E gjitha Ă«shtĂ« e thjeshtĂ« â pĂ«rshkrimi i komandĂ«s sĂ« startit.
Skedari i dytĂ« logrotateTimer.timer â ai pĂ«rcakton punĂ«n e timerĂ«ve:
[Unit]
Description=Run logrotate
[Timer]
OnBootSec=15min
OnUnitActiveSec=15min
[Install]
WantedBy=timers.targetĂfarĂ« ka kĂ«tu:
- përshkrimi i timerit
- Koha e startit të parë, duke filluar nga ngarkesa e sistemit
- periudha e lançimeve të mëtejshme
- Varësia nga shërbimi i timerëve. Në fakt, kjo është një linjë dhe bën timerin
Skirpt interaktiv kur është fikur dhe targeti yt i fikjes
NĂ« njĂ« zhvillim tjetĂ«r, mĂ« duhej tĂ« bĂ«ja njĂ« version mĂ« tĂ« komplikuar pĂ«r fikjen e makinĂ«s â pĂ«rmes njĂ« targeti tĂ« imçt, pĂ«r tĂ« kryer shumĂ« veprime. Zakonisht rekomandohet tĂ« krijohet njĂ« shĂ«rbim oneshot me opsionin RemainAfterExit, por kjo nuk ofron mundĂ«sinĂ« pĂ«r tĂ« krijuar njĂ« skript interaktiv.
BĂ«het fjalĂ« qĂ« komandat, tĂ« nisura nga opsioni ExecOnStop, ekzekutohen jashtĂ« TTY! Kontrollo thjesht â fut komandĂ«n tty dhe ruaj dalje nĂ« tĂ«.
Prandaj, unë realizova fikjen përmes targetit tim. Nuk pretendoj për 100% saktësi, por funksionon!
Si u realizua (në terma të përgjithshëm):
Krijova targetin my_shutdown.target, i cili nuk varej nga askush:
my_shutdown.target
[Unit]
Description=my shutdown
AllowIsolate=yes
Wants=my_shutdown.service Kur kaloni nĂ« kĂ«tĂ« target (nĂ«pĂ«rmjet systemctl isolate my_shutdown.target), ai aktivizonte 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 skripti ekzekutoj veprimet e nevojshme. Mund të shtoj shumë skripte në target 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/
$commandV notes. Përdorimi i skedarëve /tmp/reboot dhe /tmp/shutdown. Nuk mund të thërrasësh target me parametra. Mund të thërrasësh vetëm shërbimin.
Por përdor target për të pasur fleksibilitet në punë dhe një rend të garantuar të realizimit të veprimeve.
Megjithatë, e gjithë kjo bëhet më interesante më pas. Duhet të fiket/riniset makina. Dhe këtu ka 2 mundësi:
- TĂ« zĂ«vendĂ«soj komandat reboot, shutdown dhe tĂ« tjera (ato gjithsesi janĂ« lidhje simbole nĂ« systemctl) me skriptin tim. Brenda skriptit â kalimi nĂ« my_shutdown.target. Dhe skriptet brenda targetit mĂ« pas thĂ«rrasin direkt systemctl, pĂ«r shembull, systemctl reboot.
- Një variant më i thjeshtë, por që nuk më pëlqen. Në të gjitha ndërfaqet të thërrasësh jo shutdown/reboot/të tjera, por të thërrasësh drejtpërdrejt targetin systemctl isolate my_shutdown.target.
Zgjodha variantin e parë. Në systemd reboot (si dhe poweroff) janë lidhje simbole në systemd.
ls -l /sbin/poweroff
lrwxrwxrwx 1 root root 14 sen 30 18:23 /sbin/poweroff -> /bin/systemctlPrandaj, ato mund të zëvendësohen me skriptet e mia:
rikthim
#!/bin/sh
touch /tmp/reboot
sudo systemctl isolate my_shutdown.target
fiBurimi: habr.com
