Pour célébrer cette sortie, l'incroyable Luis Felipe López Acevedo a conçu un nouveau logo, disponible sous CC-BY-SA, et le projet s'est doté d'un site web digne de ce nom.
Voyons d'abord ce qu'est le Shepherd et ce qu'il peut faire.
En un coup d'œil
Le Shepherd est un gestionnaire de services minimaliste mais riche en fonctionnalités et, en tant que tel, il héberge des services : il garde une trace des services, de leur état et de leurs dépendances, et il peut les démarrer, les arrêter et les redémarrer en cas de besoin. C'est un travail simple ; le faire correctement et fournir aux utilisateurs un aperçu et un contrôle sur les services est une autre histoire.
Le Shepherd se compose de deux commandes : shepherd est le démon qui gère les services, et herd est la commande qui vous permet d'interagir avec lui pour inspecter et contrôler l'état des services. La commande shepherd peut s'exécuter en tant que premier processus (PID 1) et servir comme « init system », comme c'est le cas sur Guix System ; ou bien elle peut gérer les services pour les utilisateurs non privilégiés, comme c'est le cas sur Guix Home. Par exemple, l'exécution de herd status ntpd en tant que root permet de savoir ce que fait le démon NTP (Network Time Protocol) :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | $ sudo herd status ntpd ● Status of ntpd: It is running since Fri 06 Dec 2024 02:08:08 PM CET (2 days ago). Main PID: 11359 Command: /gnu/store/s4ra0g0ym1q1wh5jrqs60092x1nrb8h9-ntp-4.2.8p18/bin/ntpd -n -c /gnu/store/7ac2i2c6dp2f9006llg3m5vkrna7pjbf-ntpd.conf -u ntpd -g It is enabled. Provides: ntpd Requires: user-processes networking Custom action: configuration Will be respawned. Log file: /var/log/ntpd.log Recent messages (use '-n' to view more or less): 2024-12-08 18:35:54 8 Dec 18:35:54 ntpd[11359]: Listen normally on 25 tun0 128.93.179.24:123 2024-12-08 18:35:54 8 Dec 18:35:54 ntpd[11359]: Listen normally on 26 tun0 [fe80::e6b7:4575:77ef:eaf4%12]:123 2024-12-08 18:35:54 8 Dec 18:35:54 ntpd[11359]: new interface(s) found: waking up resolver 2024-12-08 18:46:38 8 Dec 18:46:38 ntpd[11359]: Deleting 25 tun0, [128.93.179.24]:123, stats: received=0, sent=0, dropped=0, active_time=644 secs 2024-12-08 18:46:38 8 Dec 18:46:38 ntpd[11359]: Deleting 26 tun0, [fe80::e6b7:4575:77ef:eaf4%12]:123, stats: received=0, sent=0, dropped=0, active_time=644 secs |
Il fonctionne et enregistre des messages : les derniers sont affichés ici et il est possible d'ouvrir /var/log/ntpd.log pour en voir d'autres. L'exécution de herd stop ntpd mettrait fin au processus ntpd, et il existe également une action start et restart.
Les services peuvent également avoir des actions personnalisées ; dans l'exemple ci-dessus, une action configuration a été mise en place. Il s'avère que cette action est un moyen pratique d'obtenir le nom du fichier de configuration de ntpd :
Code : | Sélectionner tout |
1 2 3 | $ head -2 $(sudo herd configuration ntpd) driftfile /var/run/ntpd/ntp.drift pool 2.guix.pool.ntp.org iburst |
Bien sûr, un système typique fait tourner un certain nombre de services, dont beaucoup dépendent les uns des autres. La commande herd graph renvoie une représentation de ce graphe de dépendance des services qui peut être envoyé à dot ou xdot pour le visualiser ; voici ce qui est obtenu sur un ordinateur portable :
Il s'agit d'un graphe assez volumineux, mais il permet de tirer quelques enseignements. Chaque nœud du graphe est un service ; les rectangles correspondent aux services « réguliers » (typiquement des démons comme ntpd), les nœuds ronds correspondent aux services « one-shot » (services qui exécutent une action et s'arrêtent immédiatement), et les losanges correspondent aux services « timed » (services qui exécutent du code périodiquement).
Estomper la frontière entre utilisateur et développeur
Une caractéristique unique de Shepherd est que vous le configurez et l'étendez dans son propre langage d'implémentation : en Guile Scheme. Cela ne signifie pas que vous devez être un expert dans ce langage de programmation pour commencer. Au contraire, il s'agit de faire en sorte que n'importe qui puisse commencer simplement avec son fichier de configuration et apprendre progressivement à en faire plus si et quand il en ressent le besoin. Avec cette approche, l'utilisateur reste dans la boucle, comme l'a dit Andy Wingo.
Un fichier de configuration Shepherd est un extrait Scheme qui se présente comme suit :
Code : | Sélectionner tout |
1 2 3 4 5 | (register-services (list (service '(ntpd) ) )) (start-in-the-background '(ntpd )) |
Ici, nous définissons ntpd et le démarrons dès que shepherd a lu le fichier de configuration. Les ellipses peuvent être complétées par d'autres services.
Par exemple, le service ntpd est défini comme suit :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | (service '(ntpd) #:documentation "Run the Network Time Protocol (NTP) daemon." #:requirement '(user-processes networking) #:start (make-forkexec-constructor (list " /bin/ntpd" "-n" "-c" "/ / -ntpd.conf" "-u" "ntpd" "-g") #:log-file "/var/log/ntpd.log") #:stop (make-kill-destructor) #:respawn? #t) |
Les parties importantes sont #:start bit, qui indique comment démarrer le service, et #:stop, qui indique comment l'arrêter. Dans ce cas, le programme ntpd est lancé, mais d'autres mécanismes de démarrage sont supportés par défaut : inetd, l'activation des sockets à la systemd, et les timers.
Il n'y a pas de limite à ce que #:start et #:stop peuvent faire. Dans Guix System, vous trouverez des services qui exécutent des démons dans des conteneurs, qui montent/démontent des systèmes de fichiers (comme on peut le deviner dans le graphique ci-dessus), qui mettent en place/détruisent une configuration réseau statique, et une variété d'autres choses. Le projet Swineherd va jusqu'à étendre le Shepherd pour en faire un outil de gestion des conteneurs système - similaire à ce que fait le démon Docker.
Notez que lorsque vous écrivez des définitions de services pour Guix System et Guix Home, vous visez une fine couche au-dessus de l'interface de programmation Shepherd. Comme il est d'usage dans Guix, il s'agit d'une programmation en plusieurs étapes : Les G-expressions spécifiées dans les champs start et stop sont mises en scène et se retrouvent dans le fichier de configuration Shepherd qui en résulte.
Un joli code
Il a été mentionné que Shepherd est minimaliste, et il l'est vraiment : 7.4K lignes de Scheme, sans compter les tests, selon SLOCCount. Ceci est en grande partie dû à l'utilisation d'un langage de haut niveau sans danger pour la mémoire et au fait qu'il est extensible - les fonctionnalités périphériques peuvent vivre en dehors de Shepherd.
Des avantages significatifs proviennent également du framework de concurrence : le modèle des processus séquentiels concurrents (CSP) et les Fibers. En interne, l'état de chaque service est encapsulé dans une fibre. Accéder à l'état d'un service revient à envoyer un message à sa fibre. Cette façon de structurer le code est elle-même très inspirée du modèle de l'acteur. Il en résulte un code plus simple (pas de boucle événementielle redoutée, pas d'enfer des callbacks) et une meilleure séparation des préoccupations.
L'utilisation d'un framework de haut niveau comme Fibers n'est pas sans poser de problèmes. Par exemple, il est arrivé qu'une fuite de mémoire se produise dans Fibers dans certaines conditions, et une telle situation n'est certainement pas souhaitable pour le PID 1. Mais le défi consiste vraiment à éliminer ces bogues de bas niveau pour que les fondations soient solides. Shepherd lui-même est exempt de ces problèmes de bas niveau ; sa logique est facile à raisonner et cela seul est immensément utile, il permet d'étendre le code sans crainte, et il évite les bogues de concurrence qui affligent les programmes écrits dans le style plus commun de boucle d'événements avec des callbacks.
En fait, grâce à tout cela, le Shepherd est probablement le système init le plus cool pour hacker. Il est même livré avec un REPL pour le hacking en live.
Prochaines étapes
Un certain nombre d'améliorations concrètes peuvent être apportées à Shepherd, telles que la prise en charge des services dynamiquement reconfigurables (c'est-à-dire la possibilité de redémarrer un service avec des options différentes), l'intégration des groupes de contrôle (« cgroups ») sous Linux, l'intégration correcte de la suspension logicielle, etc.
À plus long terme, il est envisagé d'entreprendre un voyage passionnant vers un Shepherd distribué et doté de capacités. Spritely Goblins fournit les fondations pour cela ; l'utiliser semble être une continuation naturelle du travail de conception de Shepherd : Goblins est un framework de modèles d'acteurs ! Juliana Sims a travaillé sur l'adaptation de Shepherd à Goblins et on a tous hâte de voir ce qui en sortira dans l'année à venir.
Source : GNU Shepherd v1.0
Et vous ?
Quel est votre avis sur le sujet ?
Avez-vous déjà utilisé cet outil ou un outil similaire pour votre usage ou le développement d'applications, et si oui, qu'en pensez-vous ?
Voir aussi :
Systemd v256 présente run0 : Une alternative plus sûre à sudo, une nouvelle approche de l'élévation de privilèges sécurisée, visant à éliminer progressivement les binaires SUID traditionnels
Linus Torvalds a annoncé la sortie du noyau Linux 6.12, et l'assortiment éclectique de changements qu'il contient en fait l'une des versions les plus importantes du noyau depuis un certain temps