
Ներածություն
Linux-ի համար մշակելու ժամանակ առաջանում են փոխազդեցային սցենարներ, որոնք կատարվում են համակարգի միացման կամ անջատման պահին: System V-ում դա հեշտ էր, բայց systemd-ն իջեցնում է փոփոխություններ: Սակայն այն ունի իր ժամանակաչափերը:
Ինչու են անհրաժեշտ target-ները
Շատերը գրում են, որ target-ները equivalent են system V -init-ի runlevel-ներին: Ես արմատապես համաձայն չեմ: Target-ները ավելի շատ են և հնարավոր է բաժանել փաթեթները խմբերով և, օրինակ, մի հրամանով սկսել ծառայությունների մի խումբ, կատարել լրացուցիչ գործողություններ: Ի վերջո, նրանց մոտ hierarchiya չկա, միայն կախվածություններ:
Target-ի օրինակ միացումը (կենսագրության հնարավորությունները) փոխադրումի փոխազդեցության սցենարի запуска:
Target-ի նկարագրություն:
cat installer.target
[Unit]
Description=Իմ տեղադրիչը
Requires=multi-user.target
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target
AllowIsolate=yes
Wants=installer.serviceԱյս target-ը կսկսվի, երբ multi-user.target-ը գործի մեջ լինի և կհիշեցնի installer.service-ին: Այս ընթացքում կարող է լինել մի քանի նման ծառայություններ:
cat installer.service
[Unit]
# նկարագրություն
Description=տեղադրողի փոխազդեցային երկխոսություն
[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-ը՝ target, որի նպատակն է համակարգը սահմանել, երբ սկսվում է: Systemd-ն գործելու է կախվածությունների երկխոսությամբ և կսկսի անհրաժեշտ ամեն ինչ:
Final.target-ը ընտրել հնարավոր է տարբեր եղանակներով, ես այդ նպատակով օգտագործել եմ բեռնման ընտրեց:
Վերջնական սկսումը նման է:
- Գործարկվում է բեռնիչը
- Բեռնիչը սկսում է ներբեռնել прошивка-ն, փոխանցելով final.target պարամետրը:
- Systemd-ն սկսում է համակարգը գործարկել: Ստիճանաբար գնում է installer.target-ին կամ work.target-ին basic.target-ի միջոցով, նրանց կախվածությունների համար (օրինակ, multi-user.target): Վերջիններս տեղափոխում են համակարգը աշխատանքային ռեժիմի:
Գործարկման համար ներբեռնում
Прошивка-ներ ստեղծելիս միշտ առաջանում է համակարգի վիճակի վերականգնման խնդիր: Այդ վիճակը ենթադրում է կոնֆիգուրացիոն ֆայլեր, տվյալների բազաների դմբփեր, ինտերֆեյսների կարգավորումներ և այլն:
Systemd-ն մեկ target-ում գործընթացները գործարկում է параллельно: Կախվածությունները պարզեցնում են սցենարների գործարկման հերթականությունը:
Ինչպես դա աշխատում է իմ նախագծում ( )
- Համակարգը սկսվում է
- Միանում է settings_restore.service ծառայությունը: Այն ստուգում է settings.txt ֆայլի առկայությունը տվյալների բաժնում: Եթե այն բացակայում է, տեղը դրվում է բնօրինակ ֆայլը: Դրանից հետո տեղի է ունենում համակարգի կարգավորումների վերականգնում:
- նետի գաղտնաբառի
- hostname,
- ժամային գոտի
- լոկալ
- Պարզել, թե արդյոք ամբողջ կրիչը օգտագործվում է։ Ձեռք բերված չափը փոքր է՝ հեշտությամբ պատճենելու և կրիչի վրա գրելու համար։ Սկզբնավորումից ստուգվում է՝ կա՞ դեռ չօգտագործված տարածք։ Եթե կա՝ սկավառակը վերաքարկվում է։
- Machine-id-ի ստեղծումը MAC հասցեից։ Դա կարևոր է DHCP միջոցով նույն հասցեն ստանալու համար։
- Անցանցային կարգավորումներ։
- Գրառումների չափը սահմանափակվում է։
- Պատրաստվում է աշխատելու արտաքին սկավառակը (եթե համապատասխան տարբերակը ակտիվացված է և սկավառակը նոր է)։
- Սկսվում է postgresq։
- Սկավառակը սկսվում է վերականգնման ծառայությունը։ Դա անհրաժեշտ է zabbix-ի և նրա տվյալների բազայի պատրաստման համար։
- Ստուգվում է, կա արդյոք արդեն zabbix տվյալների բազա։ Եթե չկա՝ այն ստեղծվում է ելքի ներմուծների (որոնք գալիս են zabbix-ի հետ)։
- Ստեղծվում է ժամացույցի գոտիների ցանկ (նրա համար անհրաժեշտ է երևակայելու web-հարթակում)։
- Գտնվում է ընթացիկ IP-ն, որը ցուցաբերական է եղել (դիմումի ընդունում ժամանելու համար)։
- Ոչխանը փոխվում է՝ հայտնվում է Ready to work արտահայտությունը։
- Նրբությունն պատրաստ է աշխատելու։
Անշուշտ կարևոր են ծառայությունների ֆայլերը, հենց նրանք սահմանում են նրանց աշխատանքի մնումը։
[Unit]
Description=վերականգնել համակարգի կարգավորումները
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Ինչպես տեսնում եք, ես սահմանել եմ կախվածություններ, որպեսզի իմ սցենարը առաջինը գործարկվի, հետո միայն ցանցը բարձրանա և սուբեկտային տվյալների բազան սկսվի։
Երկրորդ ծառայությունը (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-ի և իմ setting_restore-ի սկսվում է հետո։ Սակայն zabbix ծառայությունների սկսվելուց առաջ։
Ծառայություն ժամանակաչափի համար logrotate-ի։
Systemd կարող է փոխարինել CRON-ին։ Զգալիորեն։ Причем точность не до минуты, а до секунды (а вдруг понадобится). А можно создать монотонный таймер, вызываемый по таймауту от события.
Աκριβապես հաջորդականային ժամանակաչափ, որը հաշվում է ժամանակը մեքենայի սկսելուց հետո, ես էլ ստեղծել եմ։
Այս մեկի համար պետք է 2 ֆայլ։
logrotateTimer.service — հենց ծառայության նշումը։
[Unit]
Description=գործել logrotate
[Service]
ExecStart=logrotate \/etc\/logrotate.conf
TimeoutSec=300Բոլորը պարզ է՝ հրամանագրի նկարագիր։
Երկրորդ ֆայլը logrotateTimer.timer — սա հենց այն է, որը սահմանում է ժամանակաչափերի աշխատանքը։
[Unit]
Description=Գործել 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_shutdown.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- Այս սկրիպտի ներսում ես իրականացնում անհրաժեշտ գործողությունները։ Թիրախի մեջ կարող եք ավելացնել բազմաթիվ սկրիպտեր, Fleksibiliteti ու հարմարավետության համար:
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/այլ բաներ, այլ ուղղակի կանչում են systemctl 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Ընտանիք: habr.com
