systemd: dynamische path-unit

Alle weiteren Dienste, die nicht in die drei oberen Foren gehören.
Antworten
scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

systemd: dynamische path-unit

Beitrag von scientific » 11.01.2017 15:24:23

Hi Leute!

Ich hab mir eine schwierige Aufgabe gestellt... und jetzt konnte ich sie lösen. Ich bin mir noch nicht ganz sicher, ob die Lösung schön ist... jedenfalls scheint sie zu funktionieren. :D

Für mein Fuse-Filesystemd, mit dem ich die Drucker aus CUPS in ein Verzeichnis mounte (ein verschieben/kopieren eines Files in ein Verzeichnis für den Drucker löst damit einen Druck des Files aus, weiter nichts - und man sieht mit ls oder tree, was schon alles gedruckt wurde) wollte ich eine von XDG_DESKTOP_DIR abhängige Path-Unit für systemd - und das noch als User-Prozess...

Die Direktive "PathExists=" in der Path-Unit akzeptiert nur vollständige Pfade von / ausgehend (oder die systemd-Variablen %h für $HOME und andere mit % beginnende) und ist damit unzugänglich für ${XDG_DESKTOP_DIR}.

Ich möchte mein CupsFS aber flexibel an XDG_DESKTOP_DIR angepasst haben, und durch den User durch erstellen eines entsprechenden Verzeichnisses aktiveren lassen können. (ähnlich wie journald das journal auf die Platte schreibt, sobald das Verzeichnis /var/log/journald vorhanden ist).

Also benötige ich eine Path-Unit, welche von XDG_DESKTOP_DIR abhängig ist... Noch besser... ich lege eine eigene xdg-user-dirs-Variable XDG_PRINTERS_DIR an.

Aber Schritt für Schritt:

Zuerst gibt es eine Service-Unit, welche mir ein Environment festlegt und eine instanziierte Path-Unit aktiviert:

/etc/systemd/user/cups-fuse.service

Code: Alles auswählen

[Unit]
Description=Set XDG_PRINTERS_DIR and XDG_PRINTERS_DIR_SD and start path-unit for cups-fuse

[Service]
ExecStartPre=/bin/sh -c '/bin/systemctl --user set-environment XDG_PRINTERS_DIR=$(xdg-user-dir PRINTERS)'
ExecStartPre=/bin/sh -c '/bin/systemctl --user set-environment XDG_PRINTERS_DIR_SD=$(/bin/systemd-escape -p ${XDG_PRINTERS_DIR})'
ExecStart=/bin/systemctl --user start cups-fuse@${XDG_PRINTERS_DIR_SD}.path

[Install]
WantedBy=paths.target
Die Path-Unit sieht dann so aus:

/etc/systemd/user/cups-fuse@.path

Code: Alles auswählen

[Unit]
Description=Starts mounting printers to %f, if this directory exists

[Path]
PathExists=%f
Unit=cups-fuse@%i.service
Diese wiederum startet bei Vorhandensein des entsprechenden XDG_PRINTERS_DIR einen Service, der das CupsFS mountet.

/etc/systemd/user/cups-fuse@.service

Code: Alles auswählen

[Unit]
Description=Present directory for each printer in %f
ConditionPathExists=%f

[Service]
ExecStart=/usr/bin/CupsFS.py -f %f
ExecStop=-/bin/fusermount -u %f
Restart=on-success
Das Ganze mit Mount-Units zu lösen geht leider dynamisch nicht, da der Unit-name ja direkt den Mountpunkt wiederspiegelt. Deshalb auch die Lösung über diese drei Units.

Zu finden sind diese Units immer am aktuellen Entwicklungsstand incl. deb-Paket auf Github: https://github.com/xundeenergie/fuse-cups.git

lg scientific
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

Antworten