Systemd, skriptet interaktive dhe tajmerët

Systemd, skriptet interaktive dhe tajmerët

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.service

Ky 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.target

Dhe për fund, shembulli i skriptit të ekzekutuar:

#!/bin/bash
# ĐŸĐ”Ń€Đ”Ń…ĐŸĐŽĐžĐŒ ĐČ tty3
chvt 3
echo "Install, y/n ?"
read user_answer

E 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:

  1. Bootloader-i starton
  2. Bootloader-i fillon startimin e firmware, duke kaluar parametrin final.target
  3. 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 ( https://habr.com/ru/post/477008/ https://github.com/skif-web/monitor)

  1. Sistemi starton
  2. 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)
  3. Startohet postgresq
  4. 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Ă«)
  5. ShkĂ«putet fllanja — shfaqet fraza Ready to work
  6. 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.target

Siç 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.target

Kë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=300

E 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/
    $command

V 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/systemctl

Prandaj, ato mund të zëvendësohen me skriptet e mia:
rikthim

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

Burimi: habr.com

Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster