Sgriptiau ac amseryddion systemd, rhyngweithiol

Sgriptiau ac amseryddion systemd, rhyngweithiol

Cyflwyniad

Wrth ddatblygu ar gyfer Linux, cyfyd y dasg o greu sgriptiau rhyngweithiol sy'n cael eu gweithredu pan fydd y system yn cael ei throi ymlaen neu ei chau i lawr. Yn system V roedd hyn yn hawdd, ond gyda systemd mae'n gwneud addasiadau. Ond gall gael ei amseryddion ei hun.

Pam fod angen targedau arnom?

Mae'n cael ei ysgrifennu yn aml bod targed yn gwasanaethu fel analog o runlevel yn system V -init. Rwy'n anghytuno'n sylfaenol. Mae yna fwy ohonyn nhw a gallwch chi rannu pecynnau yn grwpiau ac, er enghraifft, lansio grΕ΅p o wasanaethau gydag un gorchymyn a pherfformio camau gweithredu ychwanegol. Ar ben hynny, nid oes ganddynt hierarchaeth, dim ond dibyniaethau.

Enghraifft o darged pan fydd wedi'i alluogi (trosolwg nodwedd) gyda sgript ryngweithiol sy'n rhedeg

Disgrifiad o'r targed ei hun:

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

Bydd y targed hwn yn dechrau pan fydd multi-user.target yn cael ei lansio a galwadau installer.service. Fodd bynnag, efallai y bydd nifer o wasanaethau o'r fath.

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

Ac yn olaf, enghraifft o'r sgript yn cael ei gweithredu:

#!/bin/bash
# ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π² tty3
chvt 3
echo "Install, y/n ?"
read user_answer

Y peth pwysicaf yw dewis final.target - y targed y dylai'r system gyrraedd ato wrth gychwyn. Yn ystod y broses gychwyn, bydd systemd yn mynd trwy'r dibyniaethau ac yn lansio popeth sydd ei angen arno.
Mae yna wahanol ffyrdd i ddewis final.target, defnyddiais yr opsiwn llwythwr ar gyfer hyn.

Mae'r lansiad terfynol yn edrych fel hyn:

  1. Mae'r cychwynnydd yn cychwyn
  2. Mae'r cychwynnwr yn dechrau lansio'r firmware trwy basio'r paramedr final.target
  3. Mae Systemd yn cychwyn cychwyn y system. Dilyniannol yn mynd i installer.target neu work.target o basic.target drwy eu dibyniaethau (er enghraifft, multi-user.target). Mae'r olaf yn dod Γ’'r system i weithio yn y modd a ddymunir.

Paratoi'r firmware ar gyfer ei lansio

Wrth greu firmware, mae'r dasg bob amser yn codi o adfer cyflwr y system wrth gychwyn a'i arbed wrth gau. Mae cyflwr yn golygu ffeiliau cyfluniad, tomenni cronfa ddata, gosodiadau rhyngwyneb, ac ati.

Systemd yn rhedeg prosesau yn yr un targed ochr yn ochr. Mae yna ddibyniaethau sy'n eich galluogi i bennu dilyniant cychwyn sgriptiau.

Sut mae'n gweithio yn fy mhrosiect ( https://habr.com/ru/post/477008/ https://github.com/skif-web/monitor)

  1. Mae'r system yn dechrau
  2. Mae'r gwasanaeth settings_restore.service yn cael ei lansio. Mae'n gwirio am bresenoldeb y ffeil settings.txt yn yr adran ddata. Os nad yw yno, yna rhoddir ffeil gyfeirio yn ei lle. Nesaf, mae gosodiadau'r system yn cael eu hadfer:
    • cyfrinair gweinyddwr
    • enw gwesteiwr
    • parth amser
    • locale
    • Penderfynu a yw pob cyfrwng yn cael ei ddefnyddio. Yn ddiofyn, mae maint y ddelwedd yn fach - er hwylustod copΓ―o a recordio i gyfryngau. Wrth gychwyn, mae'n gwirio i weld a oes lle heb ei ddefnyddio o hyd. Os oes, caiff y ddisg ei hailrannu.
    • Cynhyrchu peiriant id o gyfeiriad MAC. Mae hyn yn bwysig ar gyfer cael yr un cyfeiriad trwy DHCP
    • Gosodiadau rhwydwaith
    • Yn cyfyngu ar faint y boncyffion
    • Mae'r gyriant allanol yn cael ei baratoi ar gyfer gwaith (os yw'r opsiwn cyfatebol wedi'i alluogi a bod y gyriant yn newydd)
  3. Dechrau postgresq
  4. Mae'r gwasanaeth adfer yn dechrau. Mae angen paratoi zabbix ei hun a'i gronfa ddata:
    • Gwirio a oes cronfa ddata zabbix eisoes. Os na, mae'n cael ei greu o dympiau cychwynnol (wedi'i gynnwys gyda zabbix)
    • mae rhestr o barthau amser yn cael ei chreu (angen eu harddangos yn y rhyngwyneb gwe)
    • Mae'r IP cyfredol wedi'i ddarganfod, mae'n cael ei arddangos mewn mater (gwahoddiad i fewngofnodi i'r consol)
  5. Mae'r gwahoddiad yn newid - mae'r ymadrodd Barod i weithio yn ymddangos
  6. Mae'r firmware yn barod i'w ddefnyddio

Mae'r ffeiliau gwasanaeth yn bwysig, nhw yw'r rhai sy'n gosod dilyniant eu lansiad

[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

Fel y gallwch weld, gosodais ddibyniaethau fel y byddai fy sgript yn gweithio'n gyntaf, a dim ond wedyn y byddai'r rhwydwaith yn mynd i fyny a byddai'r DBMS yn cychwyn.

A'r ail wasanaeth (paratoi 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

Mae ychydig yn fwy cymhleth yma. Mae'r lansiad hefyd mewn multi-user.target, ond AR Γ”L dechrau'r postgresql DBMS a fy setting_restore. Ond CYN dechrau gwasanaethau zabbix.

Gwasanaeth amserydd ar gyfer logrotate

Gall systemd ddisodli CRON. O ddifrif. Ar ben hynny, nid yw'r cywirdeb hyd at y funud, ond hyd at yr ail (beth os oes ei angen) Neu gallwch greu amserydd undonog, a elwir gan derfyn amser o ddigwyddiad.
Yr amserydd undonog sy'n cyfri'r amser o ddechrau'r peiriant wnes i ei greu.
Bydd hyn yn gofyn am 2 ffeil
logrotateTimer.service - y disgrifiad gwirioneddol o'r gwasanaeth:

[Unit]
Description=run logrotate

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

Mae'n syml - disgrifiad o'r gorchymyn lansio.
Yr ail ffeil logrotateTimer.timer yw lle mae'r amseryddion yn gweithio:

[Unit]
Description=Run logrotate

[Timer]
OnBootSec=15min
OnUnitActiveSec=15min

[Install]
WantedBy=timers.target

Beth sydd yma:

  • disgrifiad amserydd
  • Amser cychwyn cyntaf, gan ddechrau o gychwyn y system
  • cyfnod o lansiadau pellach
  • Dibyniaeth ar y gwasanaeth amserydd. Mewn gwirionedd, dyma'r llinyn sy'n gwneud yr amserydd

Sgript ryngweithiol wrth gau a'ch targed cau i lawr

Mewn datblygiad arall, roedd yn rhaid i mi wneud fersiwn mwy cymhleth o ddiffodd y peiriant - trwy fy nharged fy hun, er mwyn cyflawni llawer o gamau gweithredu. Fel arfer argymhellir creu gwasanaeth un llun gyda'r opsiwn RemainAfterExit, ond mae hyn yn eich atal rhag creu sgript ryngweithiol.

Ond y ffaith yw bod y gorchmynion a lansiwyd gan yr opsiwn ExecOnStop yn cael eu gweithredu y tu allan i'r TTY! Mae'n hawdd gwirio - gludwch y gorchymyn tty ac arbed ei allbwn.

Felly, gweithredais y cau drwy fy nharged. Dydw i ddim yn honni fy mod 100% yn gywir, ond mae'n gweithio!
Sut y cafodd ei wneud (yn gyffredinol):
Creais darged my_shutdown.target, nad oedd yn dibynnu ar unrhyw un:
fy_shutdown.target

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

Wrth fynd at y targed hwn (trwy systemctl ynysu my_shutdwn.target), lansiodd y gwasanaeth my_shutdown.service, y mae ei dasg yn syml - i weithredu'r sgript 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

  • Y tu mewn i'r sgript hon rwy'n cyflawni'r gweithredoedd angenrheidiol. Gallwch ychwanegu llawer o sgriptiau at y targed ar gyfer hyblygrwydd a hwylustod:

fy_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

Nodyn. Gan ddefnyddio'r ffeiliau /tmp/reboot a /tmp/ shutdown. Ni allwch ffonio targed gyda pharamedrau. Dim ond gwasanaeth sy'n bosibl.

Ond rwy'n defnyddio targed i gael hyblygrwydd yn y gwaith a threfn warantedig o gamau gweithredu.

Fodd bynnag, daeth y peth mwyaf diddorol yn ddiweddarach. Mae angen diffodd/ailgychwyn y peiriant. Ac mae yna 2 opsiwn:

  • Disodli'r reboot, shutdown a gorchmynion eraill (maent yn dal i fod yn symlinks i systemctl) gyda'ch sgript. Y tu mewn i'r sgript, ewch i my_shutdown.target. Ac mae'r sgriptiau y tu mewn i'r targed wedyn yn galw systemctl yn uniongyrchol, er enghraifft, ailgychwyn systemctl
  • Opsiwn symlach, ond dydw i ddim yn ei hoffi. Ym mhob rhyngwyneb, peidiwch Γ’ galw cau i lawr/ailgychwyn/arall, ond ffoniwch yn uniongyrchol y systemctl targed ynysu my_shutdown.target

Dewisais yr opsiwn cyntaf. Yn systemd, mae ailgychwyn (fel poweroff) yn symlinks i systemd.

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

Felly, gallwch chi roi eich sgriptiau eich hun yn eu lle:
ailgychwyn

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

Ffynhonnell: hab.com

Ychwanegu sylw