• # Complément & commentaires

    Posté par . En réponse au journal Sur systemd, btrfs & co. Évalué à 4.

    Re,

    J’utilise quelques programmes qui ont des tâches périodiques, typiquement r2e (abréviation de rss2email) et fetchmail. Je veux pouvoir les exécuter toutes les heures.

    Je précise encore une fois que c’est du quick&dirty (ce qui me suffit très largement en l’occurrence).

    Je crée les fichiers :

    /etc/systemd/system/timers.target.wants/hourly.timer

    [Unit]
    Description=All hours
    [Timer]
    OnUnitActiveSec=1h
    Unit=hourly.target
    [Install]
    WantedBy=timers.target
    

    On introduit un nouveau type d’unité target, ça sert juste à pouvoir grouper des unités. Si je ne m’abuse, le démarrage (directive start de systemctl) d’une unité xxx.target va démarrer tout ce qui se trouve dans le dossier xxx.target.wants (d’ou cette correction avec enable dans mon commentaire un peu au-dessus, pour créer les liens symboliques qui vont bien).

    /etc/systemd/system/hourly.target

    [Unit]
    Description=For all periodic services
    

    /etc/systemd/system/fetchmail.service

    [Unit]
    Description=Retrieve emails
    After=local-fs.target network.target
    [Service]
    ExecStart=/usr/bin/fetchmail
    SuccessExitStatus=1
    User=pierre_roc
    [Install]
    WantedBy=multi-user.target hourly.target
    

    (Notez que fetchmail quitte avec le code de retour 1 lorsqu’il ne trouve aucun mails)

    /etc/systemd/system/rss2email.service

    [Unit]
    Description=Send rss as email
    After=local-fs.target network.target
    [Service]
    ExecStart=/usr/bin/r2e run
    User=pierre_roc
    [Install]
    WantedBy=multi-user.target hourly.target
    

    Puis on lance :

    sudo systemctl enable fetchmail.service
    sudo systemctl enable rss2email.service
    sudo systemctl start hourly.timer

    Enjoy ! \o/ (en théorie ça devrait fonctionner 0:) )

    ———

    Quelques commentaires (en rapport aux discussions).

    Notez que fetchmail propose déjà tout ce qu’il faut pour des logs et pour se mettre en démon. Quant à rss2email, j’ai dû créer mon propre script shell pour gérer son réveil toutes les heures, ce qui nécessite de vérifier qu’il n’y a qu’une instance lancée, d’avoir un dash->sleep 3600 dans l’arbre des processus donc en mémoire, etc.

    Tout ceci conduit à une duplication du code monstrueuse, avec trente six milles (mauvaises, surtout quand c’est moi qui les pond) ré-implémentation des mêmes fonctionnalités : pouvoir écrire des log sur stdout, dans un fichier, et sur syslog, pouvoir forker, pouvoir passer en attente passive, etc.

    On a sensiblement simplifié le procédé et mutualisé du code. C’est pourquoi il est inutile de comparer de manière brute le nombre de lignes de codes des init : c’est insuffisant.

    Enfin, c’est (toujours) du quick&dirty, il y a moyen de faire les choses plus proprement, par exemple l’utilisateur a la possibilité de créer ses propres unités, en mode utilisateur, dans ~/.config/systemd/user (cf man systemd.unit).

    Et ici, la solution permet de supprimer un script shell (qui s’occupe de r2e), et de rendre fetchmail à sa vocation première (UNIX, KISS, tout ça...). De plus, il y a un malentendu sur le shell : c’est pour moi un puissant outil lorsqu’il est question de flexibilité, de souplesse, pour élaborer ses propres solutions à des besoins particuliers.

    Le problème n’est pas le shell en soi, et évidemment, le shell est incontournable pour des scripts d’init personnalisés.

    Le problème tient de ce que petit à petit le shell ait rempli des besoins pour lesquels il n’était pas optimal : j’estime que dès lors qu’un code doit être massivement distribué, le shell devient problématique (sauf à remplir des tâches subalternes).

    C’est le cas des scripts d’init distribués usuellement avec les serveurs et démons qui tournent sur nos bécanes. Ce n’est plus du shell (sur une Gentoo qui utilise OpenRC on a #!/sbin/runscript) mais un sous-ensemble rigide (il faut renseigner un certain nombre de fonctions–variables précises typiquement), mais aussi un ajout de fonctionnalités (toujours avec OpenRC, il y a des mot-clefs à utiliser).

    Sous Debian c’est pas mieux, puisqu’on utilise les commentaires pour remplir du code. Par exemple :

    ### BEGIN INIT INFO
    # Provides: scriptname
    # Required-Start: $remote_fs $syslog
    # Required-Stop: $remote_fs $syslog
    # Default-Start: 2 3 4 5
    # Default-Stop: 0 1 6
    # Short-Description: Start daemon at boot time
    # Description: Enable service provided by daemon.
    ### END INIT INFO
    

    Entre mettre ce genre de données au début d’un script (peu lisibles qui plus est, le poids historique je suppose), ou dans un fichier séparé appelé "unité". Je trouve carrément plus propre la seconde solution.

    Bref, je trouve que dès qu’on essaie d’utiliser le shell pour autre chose que du script à usage particulier (personnel ou professionnel), on aboutit à des solutions que j’estime souvent bancales et peu rigoureuses. Le shell est un outil pour l’administrateur système, pas pour le distributeur, encore moins pour le développeur.