web-dev-qa-db-fra.com

Comment utiliser un paramètre dans la ligne de commande ExecStart?

J'essaie de convertir un script SysVintit utilisé sur Debian (et des distributions dérivées telles que LinuxMint et Ubuntu & Co.) en un service systemd à utiliser sur Fedora ou ArchLinux (et des distributions dérivées telles que Bridge ou Manjaro), mais même si le systemd le système de démarrage est plus performant et polyvalent que le précédent, je ne comprends pas comment faire des trucs simples comme utiliser un argument "optionnel" sur une ligne de commande comme ExecStart = ou ExecRestart =!

Voici ce que je fais avec SysVinit:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          myprog
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: myprog init script
# Descripton:        this script manages myprog
### END INIT INFO
# exit if myprog isn't installed
[ -x "/opt/mystuff/myrpog" ] || exit 0
case "$1" in
  start)
    cd /opt/mystuff
    ./myprog -r
    echo
    ;;
  stop)
    cd /opt/mystuff
    ./myprog -x
    ;;
  restart)
    cd /opt/mystuff
    ./myprog -x && ./myprog -r
    ;;
  version)
    cd /opt/mystuff
    ./myprog -v
    ;;
  try)
    cd /opt/mystuff
    ./myprog
    ;;
  *)
    echo "Usage: Sudo service myprog {start|stop|version|try}" >&2
    exit 3
    ;;
esac
:

Le script ci-dessus permet donc d'utiliser différents arguments dont un vide qui affichera le message "Usage: ..." lors de l'utilisation des lignes de commande suivantes:

Sudo service myprog start   => start myprog with the -r argument

Sudo service myprog stop    => stop myprog with the -x argument

Sudo service myprog version => display the release of myprog in the console

Sudo service myprog try     => start myprog without any argument

Sudo service myprog restart => stop then start myprog with the -r argument

suso service myprog         => display the "Usage:..." message in the console

Maintenant, avec systemd, le script devrait ressembler à ceci:

[Unit]
Description=This script manages myprog
ConditionFileExecutable=/opt/mystuff/myprog

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/opt/mystuf/myprog -r
ExecStop=/opt/mystuff/myprog -x
ExecRestart=/opt/mystuff/myprog -x : /opt/mystuff/myprog -r

[Install]
After=NetworkManager.service

Ici commence mes problèmes (et mon manque de connaissances système):

De toute évidence, systemd ne fournit pas de commande telle que ExecCustom01 =, ExecCustom02, etc. qui me permettrait de créer des commandes pour "version" et "try" (et d'autres si nécessaire).

Donc, je peux utiliser ExecRestart d'une manière différente si je pouvais utiliser un argument pour démarrer à la fois la commande "version" ou la commande "try" (étant dit que le redémarrage "réel" peut être fait en démarrant successivement les commandes stop et start ).

Ces commandes ExecRestart = "personnalisées" pourraient alors ressembler à ceci:

Sudo systemctl restart myprog  => without argument for the "try" command

et

Sudo systemctl restart myprog -v => for the "version" command

Le script systemd pourrait alors ressembler à ceci:

[Unit]
Description=This script manages myprog
ConditionFileExecutable=/opt/mystuff/myprog

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/opt/mystuf/myprog -r
ExecStop=/opt/mystuff/myprog -x
ExecRestart=/opt/mystuff/myprog ????? // this is where I need to use an argument

[Install]
After=NetworkManager.service

Mais je ne sais pas si c'est possible, et si oui, quelle est la syntaxe à utiliser!

Toute aide serait vraiment appréciée car même après avoir passé un tas d'heures dans les multiples pages de manuel de systemd, je n'ai trouvé aucun exemple explicite sur la façon de le faire.

TIA pour votre temps et vos conseils.

15
Fnux

Bien que systemd ne fournisse en effet aucun moyen de passer des arguments de ligne de commande pour les fichiers d'unité, il existe des possibilités d'écrire des instances: http://0pointer.de/blog/projects/instances.html

Par exemple: /lib/systemd/system/[email protected] ressemble à ceci:

[Unit]
Description=Serial Getty on %I
BindTo=dev-%i.device
After=dev-%i.device systemd-user-sessions.service

[Service]
ExecStart=-/sbin/agetty -s %I 115200,38400,9600
Restart=always
RestartSec=0

Donc, vous pouvez le démarrer comme:

$ systemctl start [email protected]
$ systemctl start [email protected]

Pour systemd, il y aura différentes instances :

$ systemctl status [email protected]
[email protected] - Getty on ttyUSB0
      Loaded: loaded (/lib/systemd/system/[email protected]; static)
      Active: active (running) since Mon, 26 Sep 2011 04:20:44 +0200; 2s ago
    Main PID: 5443 (agetty)
      CGroup: name=systemd:/system/[email protected]/ttyUSB0
          └ 5443 /sbin/agetty -s ttyUSB0 115200,38400,9600

Cela signifie également une grande possibilité d'activer et de désactiver séparément.

Bien sûr, il manque beaucoup de puissance d'analyse de ligne de commande, mais de manière courante, il est utilisé comme une sorte de sélection de fichiers de configuration. Par exemple, vous pouvez consulter Fedora openvpn @ .service: http://pkgs.fedoraproject.org/cgit/openvpn.git/tree/[email protected]

22
Hubbitus

Il n'est pas possible d'essayer directement des arguments de ligne de commande.

Une alternative pourrait être des variables d'environnement ( https://superuser.com/questions/728951/systemd-giving-my-service-multiple-arguments ).

C'est là que j'ai trouvé la réponse: http://www.freedesktop.org/software/systemd/man/systemctl.html

alors Sudo systemctl restart myprog -v - systemctl pensera que vous essayez de définir l'un de ses drapeaux, pas celui de myprog.

Sudo systemctl restart myprog someotheroption - systemctl redémarrera myprog et le service someotheroption, s'il existe.

2
Juan