Python & Systemd

Bonjour à tous, comment allez-vous?

Aujourd’hui nous allons voir comment lancer un script python au lancement de Raspbian. Rien de bien original me direz-vous, car dans plusieurs tutos sur le site, j’utilisais déjà cette technique en passant par crontab ou /etc/init.d afin de lancer mon script lors du boot de Wheezy. Mais les choses ont bien changé avec Jessie… Suivez le guide afin d’en savoir sur le démarrage de votre chère framboise.

Je ne suis toutefois pas au top dans ce domaine, donc ne prenez pas forcément mes écrits pour des paroles d’évangile, car je peux me tromper : personne n’est parfait… Toutefois, je mettrai mes sources en fin d’article si vous voulez allez plus loin…

Avant de commencer, sachez également que je ne veux pas rentrer dans LE débat… À savoir : Est-ce que systemd devait devenir ou non le programme qui gère le démarrage de Linux. Je n’ai pas le recul et les connaissances suffisantes pour dire si c’est une bonne chose ou pas… Il y a des Linuxiens bien plus à même que moi pour répondre à ce type de question…

I – La théorie

Du coup, depuis 1983 environ, on utilisait SysVinit, plus communément désigné par /etc/init.d pour ordonner l’exécution des différents services au démarrage. Comme je ne suis pas un expert (☺️), voici une explication claire et précise qui nous est offerte par le site Linux Fr : http://linuxfr.org/news/systemd-l-init-martyrise-l-init-bafoue-mais-l-init-libere

«  Lorsqu’un ordinateur démarre, il initialise les différents composants de l’ordinateur (processeur, mémoire vive, disque dur, carte graphique, etc.) et effectue quelques vérifications basiques, puis démarre le cœur du système d’exploitation : le noyau (ici, Linux). En effet, c’est la partie qui communique directement avec les périphériques comme le clavier, la souris, la mémoire ou l’écran et permet leur utilisation.

Lorsque le noyau est chargé, l’ordinateur n’est pas encore prêt à l’emploi. Le noyau délègue au système d’initialisation le lancement du reste du système, selon la configuration établie par l'administrateur. Il lance les services d'arrière-plan (montage des périphériques de stockage, configuration du réseau, messagerie…) et l'interface utilisateur, qu’elle soit graphique ou pas. 

Un init de type SysV fonctionne comme suit : il lit le fichier /etc/inittab qui lui indique quoi faire à un niveau d'exécution particulier, puis il démarre, redémarre ou arrête automatiquement les services selon le niveau choisi par l'utilisateur.

La syntaxe de ce fichier n’étant pas turing complète, les administrateurs ont préféré déléguer l’essentiel du démarrage à des scripts rc nommés dans ce fichier et appelés par init. Ces scripts sont aujourd’hui décriés à cause du travail dupliqué entre les distributions, de la difficulté réelle ou supposée de les maintenir et de leurs limites.  Le système d’init nécessite un travail d’intégration important dans la distribution ; il ne peut donc pas, la plupart du temps, être changé facilement par l’utilisateur."

Mais alors, pourquoi changer un système de démarrage s’il est utilisé depuis au moins une vingtaine d’années par toute une communauté? Eh bien la réponse nous est encore donnée par Linuxfr.org : (même lien que précédemment)

À première vue, systemd ressemble à SysV, mais la grande différence est que SysV suit une approche minimaliste qui déplace une grande partie de l'initialisation des services dans des programmes écrits en Shell et utilisant des bibliothèques externes (par exemple, « start-stop-daemon » pour l'init Debian). À contrario, systemd implémente un large éventail d'actions afin de décourager l'utilisation de scripts de lancement.

En pratique, un service SysV pour sshd a pour élément central un script, de quelques centaines de lignes (script Shell qui peut être utilisé indépendamment de l'init), alors que sous systemd le service sera généralement piloté par un fichier texte d'une dizaine de lignes (dans une syntaxe spécifique à systemd).

On vante souvent la simplicité des anciens systèmes d’init : en effet, quoi de plus simple que des fichiers textes exécutables, certes pas forcément triviaux, mais dont on peut lire l’exécution ligne par ligne ? Certes en éditant ces fichiers, on a une maîtrise totale du démarrage de l’ordinateur (à partir du moment où l’on est capable de comprendre le code). Mais modifier le système d’init en lui-même peut poser problème lors de mises à jour ou simplement parce que ce code n’a pas été testé.

Systemd remplit les mêmes fonctions que les précédents systèmes, mais il met l’accent sur la simplicité d’utilisation et sur une maîtrise du système plus poussée et moins éparpillée, ce qui est parfois vu comme l’opposé de la philosophie Unix.

Ainsi, beaucoup de choses qui nécessitaient auparavant de modifier des scripts Shell existent maintenant sous la forme d’un simple paramètre dans un fichier. Le comportement est codé dans systemd ce qui permet de mutualiser beaucoup de code et de rendre les fichiers souvent beaucoup plus courts.

Vous l’aurez peut-être compris, il y a des avantages et des inconvénients pour chaque système de démarrage… Mais je crois que la pilule a eu du mal à passer dans la communauté principalement, car comme le disent si bien les personnes de Linux Addict : http://www.linuxaddict.fr/index.php/2014/10/21/que-penser-de-systemd/

L'inconvénient est que Systemd est plutôt invasif. Il n’entend pas se contenter de gérer seulement le lancement des daemons, mais également de prendre en charge l’authentification, la gestion de l’énergie, etc … Ce qui de fait s’oppose quelque peu à la philosophie Unix qui dit qu’il vaut mieux plusieurs petits programmes qui ne s’occupent que d’une tâche à la fois bien, plutôt qu’une pieuvre qui voudrait tout faire mal (« do one thing, but do it well »).

En gros il y a les personnes pour systemd, il y a les personnes contre systemd et au milieu une masse de personne qui a bien du mal à voir la différence entre les deux lors d’une utilisation courante… 🙄

II – La bidouille

Étape 1 :

Je vais partir du principe que votre script python nécessite :

  • une connexion internet s’il y a besoin de récupérer des informations.
  • le fichier /home/pi est monté et prêt à être utilisé si vous voulez obtenir un log.
  • l’heure du système a été mise à jour par NTP, bien pratique pour poster sur les réseaux sociaux par exemple.
  • mon fichier script python est dans le dossier /home/pi et ce prénomme « monscript.py » .
Étape 2 :

Il nous faut créer un fichier de configuration qui indique à systemd quoi faire et quand… Pour cela :

sudo nano /lib/systemd/system/myscript.service

Ajoutez le code suivant dedans :

[Unit]
Description=My Script Service
After=multi-user.target

[Service]
Type=idle
ExecStart=/usr/bin/python /home/pi/myscript.py

[Install]
WantedBy=multi-user.target

Un petit [Ctrl+X], [Y] puis Entrée afin de sauvegarder notre nouveau fichier.

Dans le premier paragraphe Unit, on décrit notre service. Puis on demande que notre requête soit amorcée une fois que l’environment multi-user est lancé, donc après que notre ordinateur a démarrer le noyau et à charger beaucoup de modules comme par exemple le module réseau…

Dans le second paragraphe Service, le paramètre ExecStart permet de spécifier quelle commande on veut exécuter. Il est à noter que les chemins sont à déclarer de manière absolue et non relative. Le Type « idle »  permet de s’assurer que ExecStart sera seulement lancé une fois que tout le reste aura été chargé.

Enfin, dans le dernier paragraphe Install, on indique à systemd à quel niveau appartient notre service.

Petit plus, si vous voulez obtenir un fichier log pour faire du debug, car vous avez mis des print() dans votre script il faut modifier la ligne ExecStart en :

ExecStart=/usr/bin/python /home/pi/myscript.py > /home/pi/myscript.log 2>&1

Ensuite, il faut appliquer les bons droits à notre fichier service :

sudo chmod 644 /lib/systemd/system/myscript.service

On fait prendre en compte notre fichier *.service par systemd :

sudo systemctl daemon-reload

On indique à systemd de lancer notre service à chaque boot :

sudo systemctl enable myscript.service

Puis on redémarre notre Raspberry Pi :

sudo reboot

Une fois que celui-ci a redémarré, vous pouvez vérifier que votre script est bien lancé avec la commande suivante :

sudo systemctl status myscript.service

@Bientôt Anders

III – Sources :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.

Traduction :