Comment écrire un fichier .service systemd exécutant systemd-tmpfiles

16

Je dois exécuter systemd-tmpfiles --creatependant le processus de démarrage avec une distribution systemd. J'ai donc besoin de créer un fichier .service systemd faisant ce travail.

Dans cette question, vous pouvez lire tous les détails sur ce dont j'ai besoin et pourquoi: Comment fonctionnent les fichiers systemd-tmp?

J'ai lu quelques documents à ce sujet et j'écris le test suivant:

[Unit]
Description=Execute tmpfiles to disable usb-wakeup # see details in the link above
Requires=multi-user.target # see details in the link above
After=multi-user.target    # see details in the link above

[Service]
Type=oneshot
ExecStart=/usr/bin/systemd-tmpfiles --create

[Install]
WantedBy=multi-user.target

Mais je ne suis pas sûr, car ce systemd-tmpfilesn'est pas un simple programme mais un morceau de systemd lui-même. Je ne voudrais pas casser mon système.

Des conseils sur un fichier .service correct?

eang
la source
Consultez la documentation abondante sur systemd sur freedesktop.org/wiki/Software/systemd . Vous pouvez remplacer les valeurs par défaut du système par vos propres fichiers.
vonbrand

Réponses:

30

[Cela ne règle pas directement le problème des fichiers systemd-tmp mais je pense que vous avez déjà reconnu que dans ce cas particulier, il vaut mieux utiliser simplement echo.]

Tout d'abord, "multi-user.target" peut ou non être ce que vous souhaitez utiliser. Si vous êtes familier avec le concept de niveaux d'exécution à partir de choses init de style SysV, multi-utilisateur est l'équivalent systemd de runlevel 3, qui est un système multi-utilisateur qui démarre sur une console, pas une interface graphique. L'équivalent du niveau d'exécution 5, qui démarre à X, est graphical.target . La valeur par défaut est déterminée par un lien symbolique dans /etc/systemd/system(et / ou /lib/systemd/system; celui dans /etcremplacera celui dans /lib) appelé default.target , utilisez ls pour trouver où il pointe:

»ls -l /etc/systemd/system/default.target
default.target -> /usr/lib/systemd/system/multi-user.target

Pour les bureaux Linux normaux, ce sera graphical.target. Ce n'est en fait pas important si vous voulez que le service de démarrage que vous créez démarre quel que soit le niveau d'exécution / la cible par défaut - dans ce cas, nous pouvons simplement utiliser default.target, et ne vous inquiétez pas pour ce qu'il est un alias. Cependant, si vous utilisez plusieurs utilisateurs et que votre valeur par défaut est graphique, votre service ne se produira pas.

Selon le service, il peut y avoir des cibles ou des services plus appropriés et spécifiques auxquels vous souhaitez démarrer celui-ci. Sur la base de votre autre question, default.target est probablement correct. Comme note, la différence entre une "cible" et un "service" est qu'un service contient une [Service]section qui exécute réellement un processus; un objectif n'est qu'un moyen de regrouper des services via les différentes directives «dépend» et «requiert»; il ne fait rien d'autre que de déclencher d'autres cibles ou services.

Le démarrage d'un service est déterminé par les autres services qui en dépendent explicitement. Dans le cas d'un événement simple et autonome comme celui-ci que nous voulons exécuter tard dans le processus de démarrage, nous pouvons utiliser cette combinaison de directives:

[Unit]
After=default.target

[Install]
WantedBy=default.target

La section "Installer" est utilisée lors de l'installation du service; "WantedBy" spécifie une cible avec laquelle nous voulons que ce service soit inclus (ce qui signifie qu'il s'exécutera si cette cible le fait, mais nb. Cela ne détermine pas quand il s'exécutera par rapport aux autres ). Puisque nous voulons réellement que ce service s'exécute plus tard que plus tôt, nous spécifions alors une clause "After". Cela n'a pas besoin d'être identique à la cible WantedBy (ce n'est généralement pas le cas) et peut être complètement omis si vous ne vous en souciez pas quand cela se produit; Je ne fais que l'utiliser sur le pressentiment que la plupart des autres choses seront exécutées par rapport à des choses qui sont quelque part enchaînées à quelque chose qui a été spécifié Before=default.target(que nous aurions également pu utiliser; les désirs d'une cible sont évalués avant que la cible ne soit exécutée).

Pour l'exemple, je vais juste faire écho à "hello world" sur la console. Le service lui-même est décrit dans la [Service]section:

[Service]
Type=forking
ExecStart=/usr/local/bin/helloworld

La commande a besoin d'un chemin complet. La raison pour laquelle je n'ai pas simplement utilisé /usr/bin/echo "hello world"est que cela ne fonctionnera pas (la sortie va à / dev / null, je pense), et bien qu'un service qui fasse une echo "hello world" > /dev/consolevolonté, l'expérimentation démontre que l'utilisation de la redirection de shell dans une directive ExecStart ne fonctionnera pas . Donc / usr / bin local / / helloworld est un script shell avec cette ligne un, echo "hello world" > /dev/console.

Notez le Type=forking, qui est nécessaire pour un script shell.

Notre dossier de service complet, un minimum est seulement ces trois sections ( [Unit], [Service]et [Install]). Pour l'installer, placez le fichier ou un lien symbolique vers celui-ci dans / etc / systemd / system ou / usr / lib / systemd / system, et:

systemctl --system enable helloworld

Il devrait s'imprimer ln -s .... Cela n'exécute pas le service, il le configure simplement pour s'exécuter au démarrage, comme indiqué ci-dessus.

C'est tout en un mot. man systemd.unitet man systemd.serviceavoir plus de détails.

boucle d'or
la source
1
Merci, réponse très utile et problème résolu. Juste une note, dans mon distro (Chakra Linux) default.targetn'est pas /etc/systemd/system, mais il est seulement/usr/lib/systemd/system
Eang
La sortie des commandes est enregistrée (où d'autre pourrait-elle aller)?
vonbrand
Les fichiers / usr / lib / systemd / ... sont de remplacement (par défaut), vous êtes censé déposer le vôtre dans / etc / systemd / ...
vonbrand
Ces jours default.targetse trouvent dans/lib/systemd/system/default.target
czerasz
1
@czerasz Je le remarque sur Fedora 27, si je systemctl set-default ...laisse un lien symbolique /etc/systemd/systemdedans, mais cela ne change pas l'un /lib, c'est- à -dire qu'ils pointent vers des cibles différentes, mais les choses dans la première doivent remplacer la seconde. Si vous l'avez réglé vous-même, c'est ce qui peut arriver. Quoi qu'il en soit, j'ai édité dans les deux endroits.
goldilocks
2

Pour le service systemd-tmpfiles: il devrait être fourni avec votre distribution, mais vous pouvez toujours obtenir le fichier de service à partir du référentiel git en amont

SimonPe
la source