
Présentation
Lors du dĂ©veloppement pour Linux, il existe des tĂąches de crĂ©ation de scripts interactifs qui sont exĂ©cutĂ©s lorsque le systĂšme est allumĂ© ou arrĂȘtĂ©. Dans le systĂšme V, cela a Ă©tĂ© fait facilement, mais avec systemd il fait des ajustements. Mais il peut faire ses temporisations.
Pourquoi avons-nous besoin d'un objectif
Il est souvent écrit que la cible sert d'analogue du niveau d'exécution dans le systÚme V -init. Je suis fondamentalement en désaccord. Il y en a plus et vous pouvez séparer les packages en groupes et, par exemple, exécuter un groupe de services avec une équipe et effectuer des actions supplémentaires. De plus, ils n'ont pas de hiérarchie, seulement des dépendances.
Exemple cible au démarrage (présentation des fonctionnalités) avec le lancement d'un script interactif
Description de la cible elle-mĂȘme:
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
Cette cible démarre lorsque multi-user.target est lancé et appelle installer.service. De plus, il peut y avoir plusieurs de ces services.
cat installer.service [Unit]
Et enfin, un exemple de script exécutable:
La chose la plus importante est de choisir final.target - target, auquel le systÚme devrait parvenir au démarrage. Au cours du démarrage, systemd passera par les dépendances et exécutera tout ce dont vous avez besoin.
Il existe plusieurs façons de sélectionner final.target, j'ai utilisé l'option bootloader pour cela.
Le lancement final ressemble Ă ceci:
- Le chargeur de démarrage démarre
- Le chargeur de démarrage démarre le firmware en passant le paramÚtre final.target
- Systemd démarre le démarrage du systÚme. Il va séquentiellement à installer.target ou work.target à partir de basic.target via leurs dépendances (par exemple, multi-user.target). Ces derniers et conduisent le systÚme à fonctionner dans le mode souhaité
Préparation du firmware pour le lancement
Lors de la crĂ©ation du micrologiciel, il est toujours nĂ©cessaire de restaurer l'Ă©tat du systĂšme au dĂ©marrage et de l'enregistrer lorsqu'il est Ă©teint. Ătat signifie les fichiers de configuration, les vidages de base de donnĂ©es, les paramĂštres d'interface, etc.
Systemd lance le processus dans une cible en parallÚle. Il existe des dépendances qui vous permettent de déterminer la séquence d'exécution du script.
Comment cela fonctionne dans mon projet ( https://habr.com/en/post/477008/ https://github.com/skif-web/monitor )
- Le systÚme démarre
- Le service settings_restore.service démarre. Il vérifie le fichier settings.txt dans la section données. S'il n'est pas là , le fichier de référence est mis à sa place. Ensuite, les paramÚtres systÚme sont restaurés:
- mot de passe administrateur
- nom d'hĂŽte
- fuseau horaire
- locale
- Détermine si tous les supports sont utilisés. Par défaut, la taille de l'image est petite - pour faciliter la copie et l'enregistrement sur un support. Au démarrage, il est vérifié s'il reste de l'espace inutilisé. S'il y a - le disque est repartitionné.
- GĂ©nĂ©rez l'ID d'ordinateur Ă partir de l'adresse MAC. Ceci est important pour obtenir la mĂȘme adresse via DHCP.
- ParamÚtres réseau
- La taille du journal est limitée
- Le lecteur externe est prĂȘt pour le travail (si l'option correspondante est activĂ©e et que le lecteur est nouveau)
- Exécutez postgresq
- le service de restauration dĂ©marre. Il est nĂ©cessaire de prĂ©parer zabbix lui-mĂȘme et sa base de donnĂ©es:
- Vérifie s'il existe déjà une base de données zabbix. Sinon, il est créé à partir de l'initialisation des vidages (ils sont fournis avec zabbix)
- une liste de fuseaux horaires est créée (nécessaire pour les afficher dans l'interface web)
- L'IP actuelle est trouvée, elle est affichée en cause (invitation à entrer dans la console)
- L'invitation change - la phrase PrĂȘt Ă travailler apparaĂźt
- Le firmware est prĂȘt Ă fonctionner.
Les fichiers de service sont importants, ce sont eux qui fixent la séquence de leur lancement
[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
Comme vous pouvez le voir, j'ai fait les dépendances pour que je puisse d'abord exécuter mon script, et alors seulement le réseau augmenterait et le SGBD démarrerait.
Et le deuxiÚme service (préparation de zabbix)
C'est un peu plus compliquĂ©. Le lancement se fait Ă©galement dans multi-user.target, mais APRĂS avoir exĂ©cutĂ© le SGBD postgresql et mon setting_restore. Mais AVANT d'exĂ©cuter les services zabbix.
Service avec une minuterie pour logrotate
Systemd peut remplacer CRON. Sérieusement. De plus, la précision n'est pas jusqu'à une minute, mais jusqu'à une seconde (et si elle est nécessaire) et vous pouvez créer une minuterie monotone, appelée par timeout depuis l'événement.
C'est la minuterie monotone qui compte le temps depuis le début de la machine que j'ai créée.
Cela nécessitera 2 fichiers
logrotateTimer.service - la description réelle du service:
[Unit] Description=run logrotate [Service] ExecStart=logrotate /etc/logrotate.conf TimeoutSec=300
C'est simple - une description de la commande de lancement.
Le deuxiÚme fichier logrotateTimer.timer est ce qui définit les minuteries pour fonctionner:
[Unit] Description=Run logrotate [Timer] OnBootSec=15min OnUnitActiveSec=15min [Install] WantedBy=timers.target
Qu'y a-t-il:
- description de la minuterie
- PremiÚre fois à partir du démarrage du systÚme
- période de nouveaux lancements
- Dépendance du service du minuteur. En fait, c'est la ligne qui rend le minuteur
Script interactif sur l'arrĂȘt et la cible d'arrĂȘt personnalisĂ©
Dans un autre dĂ©veloppement, j'ai dĂ» crĂ©er une version plus complexe de l'arrĂȘt de la machine - via ma propre cible, afin d'effectuer de nombreuses actions. Il est gĂ©nĂ©ralement recommandĂ© de crĂ©er le service oneshot avec l'option RemainAfterExit, mais cela empĂȘche la crĂ©ation d'un script interactif.
Mais le fait est que les commandes lancées par l'option ExecOnStop sont exécutées en dehors de TTY! La vérification est simple - insérez la commande tty et enregistrez sa sortie.
Par consĂ©quent, j'ai implĂ©mentĂ© l'arrĂȘt via ma cible. Je ne prĂ©tends pas ĂȘtre Ă 100% correct, mais ça marche!
Comment cela a été fait (en termes généraux):
Créé la cible my_shutdown.target, qui ne dépendait de personne:
my_shutdown.target
[Unit] Description=my shutdown AllowIsolate=yes Wants=my_shutdown.service
Lors du passage à cette cible (via systemctl isolate my_shutdwn.target), il a lancé le service my_shutdown.service, dont la tùche est simple - pour exécuter le script 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
- Dans ce script, j'effectue les actions nécessaires. Vous pouvez ajouter de nombreux scripts à la cible, pour plus de flexibilité et de commodité:
my_shutdown.sh
Remarque Utilisation des fichiers / tmp / reboot et / tmp / shutdown. Vous ne pouvez pas appeler target avec des paramĂštres. Vous ne pouvez que le service.
Mais j'utilise target afin d'avoir une flexibilité dans le travail et une séquence d'actions garantie.
Cependant, la chose la plus intĂ©ressante a Ă©tĂ© plus tard. La machine doit ĂȘtre Ă©teinte / redĂ©marrĂ©e. Et il y a 2 options:
- Remplacez les commandes reboot, shutdown et autres (ce sont toujours des liens symboliques sur systemctl) par votre propre script. Dans le script, accédez à my_shutdown.target. Et les scripts à l'intérieur de la cible appellent alors directement systemctl, par exemple, systemctl reboot
- Un plus simple, mais je n'aime pas l'option. Dans toutes les interfaces, n'appelez pas shutdown / reboot / others, mais appelez directement le systemctl cible isolate my_shutdown.target
J'ai choisi la premiÚre option. Dans systemd, le redémarrage (comme poweroff) sont des liens symboliques sur systemd.
ls -l /sbin/poweroff lrwxrwxrwx 1 root root 14 30 18:23 /sbin/poweroff -> /bin/systemctl
Par consĂ©quent, ils peuvent ĂȘtre remplacĂ©s par vos propres scripts:
redémarrer