Համակարգված, ինտերակտիվ սցենարներ և ժամանակաչափեր

Համակարգված, ինտերակտիվ սցենարներ և ժամանակաչափեր

Ներածություն

Linux-ի համար մշակելիս խնդիր է առաջանում ստեղծել ինտերակտիվ սկրիպտներ, որոնք գործարկվում են, երբ համակարգը միացված է կամ անջատվում է: V համակարգում դա հեշտ էր, բայց systemd-ով այն ճշգրտումներ է անում: Բայց այն կարող է ունենալ իր ժամանակաչափերը:

Ինչու՞ են մեզ անհրաժեշտ թիրախները:

Հաճախ գրվում է, որ թիրախը V -init համակարգում ծառայում է որպես runlevel-ի անալոգ: Ես սկզբունքորեն համաձայն չեմ. Դրանք ավելի շատ են, և դուք կարող եք փաթեթները բաժանել խմբերի և, օրինակ, մեկ հրամանով գործարկել ծառայությունների խումբ և կատարել լրացուցիչ գործողություններ: Ավելին, նրանք չունեն հիերարխիա, միայն կախվածություն:

Թիրախի օրինակ, երբ միացված է (հատկանիշի ակնարկ) գործարկվող ինտերակտիվ սցենարով

Ինքն թիրախի նկարագրությունը.

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

Այս թիրախը կսկսվի, երբ multi-user.target-ը գործարկվի և զանգի installer.service: Այնուամենայնիվ, կարող են լինել մի քանի նման ծառայություններ:

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

Եվ վերջապես, կատարվող սցենարի օրինակ.

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

Ամենակարևորը final.target-ի ընտրությունն է՝ այն թիրախը, որին համակարգը պետք է հասնի գործարկման ժամանակ: Գործարկման գործընթացում systemd-ը կանցնի կախվածությունների միջով և կգործարկի այն ամենը, ինչ անհրաժեշտ է:
Կան final.target ընտրելու տարբեր եղանակներ, ես դրա համար օգտագործել եմ loader տարբերակը։

Վերջնական մեկնարկն այսպիսի տեսք ունի.

  1. Բեռնախցիկը սկսվում է
  2. Bootloader-ը սկսում է գործարկել որոնվածը` անցնելով final.target պարամետրը
  3. Systemd-ը սկսում է գործարկել համակարգը: Հերթականորեն գնում է installer.target կամ work.target հիմնական.target-ից իրենց կախվածությունների միջոցով (օրինակ՝ multi-user.target): Վերջիններս համակարգը աշխատանքի են բերում ցանկալի ռեժիմով

Ծրագրաշարի պատրաստում գործարկման համար

Որոնվածը ստեղծելիս միշտ խնդիր է առաջանում վերականգնել համակարգի վիճակը գործարկման ժամանակ և պահպանել այն անջատելիս: Պետությունը նշանակում է կազմաձևման ֆայլեր, տվյալների բազայի աղբանոցներ, ինտերֆեյսի կարգավորումներ և այլն:

Systemd-ը զուգահեռաբար կատարում է գործընթացները նույն թիրախում: Կան կախվածություններ, որոնք թույլ են տալիս որոշել սկրիպտների գործարկման հաջորդականությունը:

Ինչպես է այն աշխատում իմ նախագծում ( https://habr.com/ru/post/477008/ https://github.com/skif-web/monitor)

  1. Համակարգը սկսվում է
  2. Գործարկվում է settings_restore.service ծառայությունը, որը ստուգում է տվյալների բաժնում settings.txt ֆայլի առկայությունը: Եթե ​​այն չկա, ապա դրա տեղում տեղադրվում է տեղեկատու ֆայլ: Հաջորդը, համակարգի կարգավորումները վերականգնվում են.
    • ադմինիստրատորի գաղտնաբառը
    • հյուրընկալողի անունը,
    • Ժամային գոտի
    • տեղայնությունը
    • Որոշում է, թե արդյոք օգտագործվում են բոլոր լրատվամիջոցները: Լռելյայնորեն, պատկերի չափը փոքր է. պատճենելու և մեդիա ձայնագրման հեշտության համար: Գործարկման ժամանակ այն ստուգում է՝ արդյոք դեռ չօգտագործված տարածք կա: Եթե ​​կա, ապա սկավառակը վերաբաշխվում է:
    • Մեքենայի ID-ի ստեղծում MAC հասցեից: Սա կարևոր է DHCP-ի միջոցով նույն հասցեն ստանալու համար
    • Ցանցի կարգավորումներ
    • Սահմանափակում է գերանների չափերը
    • Արտաքին սկավառակը պատրաստվում է աշխատանքի (եթե համապատասխան տարբերակը միացված է և սկավառակը նոր է)
  3. Սկսեք postgresq
  4. Վերականգնման ծառայությունը սկսվում է: Այն անհրաժեշտ է ինքնին zabbix-ը և դրա տվյալների բազան պատրաստելու համար.
    • Ստուգում է՝ արդյոք արդեն կա zabbix տվյալների բազա: Եթե ​​ոչ, այն ստեղծվում է սկզբնավորման աղբանոցներից (ներառյալ zabbix-ը)
    • ստեղծվում է ժամային գոտիների ցանկ (անհրաժեշտ է դրանք վեբ ինտերֆեյսում ցուցադրելու համար)
    • Ընթացիկ IP-ն գտնվել է, այն ցուցադրվում է հարցում (վահանակ մուտք գործելու հրավեր)
  5. Հրավերը փոխվում է՝ հայտնվում է Ready to work արտահայտությունը
  6. Որոնվածը պատրաստ է օգտագործման

Ծառայության ֆայլերը կարևոր են, դրանք են, որոնք սահմանում են դրանց գործարկման հաջորդականությունը

[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

Ինչպես տեսնում եք, ես տեղադրեցի կախվածություններ, որպեսզի իմ սցենարը սկզբում աշխատի, և միայն դրանից հետո ցանցը բարձրանա և սկսվի DBMS-ը։

Եվ երկրորդ ծառայությունը (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

Այստեղ մի փոքր ավելի բարդ է: Գործարկումը նույնպես multi-user.target-ում է, բայց postgresql DBMS-ն ու իմ setting_restore-ը սկսելուց ՀԵՏՈ: Բայց մինչ zabbix ծառայությունները սկսելը:

Ժամաչափի ծառայություն logrotate-ի համար

Systemd-ը կարող է փոխարինել CRON-ին: Լուրջ. Ընդ որում, ճշգրտությունը մինչև րոպեն չէ, այլ մինչև վայրկյանը (բա եթե դրա կարիքը լինի) Կամ կարող եք ստեղծել միապաղաղ ժմչփ, որը կոչվում է իրադարձության ժամանակացույցով:
Դա միապաղաղ ժմչփն էր, որը հաշվում է ժամանակը իմ ստեղծած մեքենայի մեկնարկից:
Սա կպահանջի 2 ֆայլ
logrotateTimer.service - ծառայության իրական նկարագրությունը.

[Unit]
Description=run logrotate

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

Դա պարզ է՝ գործարկման հրամանի նկարագրությունը:
Երկրորդ ֆայլը logrotateTimer.timer այն վայրն է, որտեղ աշխատում են ժամանակաչափերը.

[Unit]
Description=Run logrotate

[Timer]
OnBootSec=15min
OnUnitActiveSec=15min

[Install]
WantedBy=timers.target

Ինչ կա այստեղ.

  • ժմչփի նկարագրություն
  • Առաջին մեկնարկի ժամանակը, սկսած համակարգի բեռնումից
  • հետագա գործարկումների ժամանակահատվածը
  • Կախվածություն ժմչփի ծառայությունից: Փաստորեն, սա այն տողն է, որը ստեղծում է ժամանակաչափը

Ինտերակտիվ սցենար անջատման ժամանակ և ձեր անջատման թիրախը

Մեկ այլ մշակման ժամանակ ես պետք է անեի մեքենան անջատելու ավելի բարդ տարբերակ՝ իմ սեփական թիրախի միջոցով, որպեսզի կատարեի բազմաթիվ գործողություններ: Սովորաբար խորհուրդ է տրվում ստեղծել oneshot ծառայություն RemainAfterExit տարբերակով, սակայն դա ձեզ խանգարում է ստեղծել ինտերակտիվ սցենար:

Բայց փաստն այն է, որ ExecOnStop տարբերակով գործարկված հրամանները կատարվում են TTY-ից դուրս: Հեշտ է ստուգել՝ տեղադրեք tty հրամանը և պահպանեք դրա արդյունքը:

Հետևաբար, ես իրականացրեցի անջատումը իմ թիրախի միջոցով: Ես չեմ պնդում, որ 100% ճիշտ եմ, բայց դա աշխատում է:
Ինչպես դա արվեց (ընդհանուր ձևով).
Ես ստեղծեցի թիրախ my_shutdown.target, որը կախված չէր որևէ մեկից.
my_shutdown.target

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

Այս թիրախին անցնելիս (systemctl isolate my_shutdwn.target-ի միջոցով), այն գործարկեց my_shutdown.service ծառայությունը, որի խնդիրը պարզ է՝ գործարկել 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

  • Այս սցենարի ներսում ես կատարում եմ անհրաժեշտ գործողությունները: Ճկունության և հարմարության համար կարող եք թիրախին ավելացնել բազմաթիվ սցենարներ.

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

Նշում. Օգտագործելով /tmp/reboot և /tmp/shutdown ֆայլերը: Դուք չեք կարող զանգահարել թիրախը պարամետրերով: Հնարավոր է միայն սպասարկում։

Բայց ես օգտագործում եմ թիրախը աշխատանքի մեջ ճկունություն և գործողությունների երաշխավորված կարգ ունենալու համար։

Այնուամենայնիվ, ամենահետաքրքիրը եկավ ավելի ուշ. Մեքենան պետք է անջատվի/վերագործարկվի: Եվ կա 2 տարբերակ.

  • Փոխարինեք reboot, shutdown և այլ հրամանները (դրանք դեռևս systemctl-ի սիմվոլիկներ են) ձեր սկրիպտով: Սկրիպտի ներսում գնացեք my_shutdown.target: Իսկ թիրախի ներսում գտնվող սկրիպտները անմիջապես կանչում են systemctl, օրինակ՝ systemctl reboot
  • Ավելի պարզ տարբերակ, բայց ինձ դուր չի գալիս: Բոլոր ինտերֆեյսներում մի զանգահարեք shutdown/reboot/other, այլ ուղղակիորեն զանգահարեք թիրախային համակարգըctl isolate my_shutdown.target:

Ես ընտրեցի առաջին տարբերակը. Systemd-ում reboot-ը (ինչպես poweroff-ը) սիմվոլիկ է systemd-ին:

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

Հետևաբար, դուք կարող եք դրանք փոխարինել ձեր սեփական սցենարներով.
reboot

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

Source: www.habr.com

Добавить комментарий