Systemd - path

systemd-path

Die grundlegenden und einführenden Informationen zu Systemd enthält die Handbuchseite Systemd-Start Die alle Unit-Dateien betreffenden Sektionen [Unit] und [Install] behandelt unsere Handbuchseite Systemd Unit-Datei.
In der vorliegenden Handbuchseite erklären wir die Funktion der Unit systemd.path, mit der systemd Pfade überwacht und Pfad-basierte Aktionen auslöst.

Die “.path-Unit” ermöglicht es, bei Änderungen an Dateien und Verzeichnissen (Pfaden) eine Aktion auszulösen.
Sobald ein Ereignis eintritt, kann Systemd einen Befehl oder ein Skript über eine Service-Unit ausführen. Die “.path-Unit” ist nicht in der Lage Verzeichnisse rekursiv zu überwachen. Es können aber mehrere Verzeichnisse und Datein angegeben werden.
Die Pfad-spezifischen Optionen werden in dem Abschnitt [Path] konfiguriert.

Benötigte Dateien

Die systemd-path-Unit benötigt für ihre Funktion mindestens zwei Dateien mit vorzugsweise dem gleichen Namen, aber unterschiedlicher Namenserweiterung im Verzeichnis /usr/local/lib/systemd/system/. (Ggf. ist das Verzeichnis zuvor mit dem Befehl mkdir -p /usr/local/lib/systemd/system/ anzulegen.) Das sind die

path-Unit Optionen

Die .path-Unit muss zwingend die Sektion [Path] enthalten, in der festgelegt wird wie und was zu überwachen ist.

Die speziellen Optionen sind:

Ein Beispiel

Auf der Konfiguration des Apache-Webservers entsprechend unserer Handbuchseite LAMP - Apache, Benutzer und Rechte basierend, wollen wir das Zusammenspiel der .path-Unit mit anderen systemd-Unit verdeutlichen.

Die Abbildung path-Unit-Funktion stellt die Abhängigkeiten der systemd-Units unseres Beispiels dar.

path-Unit Funktion

Der doppelt umrandete Teil in der Graphik verdeutlicht die Kernfunktion der .path-Unit. Die server1.path-Unit überwacht die Datei “/var/www/changed” und aktiviert bei Änderungen die zugehörige server1.service-Unit. Diese wiederum führt dann die gewünschten Aktionen im Verzeichnis “/var/www/html/” aus und stellt die Datei “/var/www/changed” zurück.
Die außerhalb der Umrandung liegende “server1-watch.service”-Unit übernimmt die rekursive Überwachung von DocumentRoot des Apache-Webservers.

path-Unit anlegen

Wir legen die Datei server1.path im Verzeichnis /usr/local/lib/systemd/system/, die die Datei /var/www/changed auf Änderungen überwacht, mit folgendem Inhalt an:

[Unit]
Description=Monitoring "changed" file!
BindsTo=server1-watch.service
After=server1-watch.service

[Path]
PathModified=/var/www/changed

[Install]
WantedBy=multi-user.target

Erklärungen
Sektion [Unit]:
Die Option “BindsTo=” stellt die stärkste verfügbare Bindung zweier systemd-Einheiten aneinander dar. Falls eine von ihnen während des Starts oder des Betriebs in einen Fehlerzustand übergeht, wird die andere auch unmittelbar beendet.
Zusammen mit der Option “After=” wird erreicht, dass die server1.path-Unit erst startet, nachdem die server1-watch.service-Unit ihren erfolgreichen Start an systemd zurückmeldet.

Sektion [Path]:
PathModifid=” ist die richtige Wahl. Die Option reagiert auf Änderungen in der Datei /var/www/changed, selbst wenn die Datei nicht geschlossen wird.
Die Option “PathModifid=” (oder andere, siehe oben) kann mehrfach angegeben werden.

service-Unit für path

Die server1.service-Unit wird von der server1.path-Unit aktiviert und kontrolliert und benötigt daher keine [Install] Sektion. Somit reichen die Beschreibung der Unit in der Sektion [Unit], und in der Sektion [Service] die auszuführenden Befehle, aus.

Wir legen die Datei server1.service im Verzeichnis /usr/local/lib/systemd/system/ mit folgendem Inhalt an.

[Unit]
Description=Change permissions in server1 folder

[Service]
Type=oneshot
ExecStartPre=/usr/bin/truncate -s 0 /var/www/changed
ExecStart=/usr/bin/chown -R www-data /var/www/html/
ExecStart=/usr/bin/chmod -R g+w /var/www/html/
ExecStart=/usr/bin/chmod -R o-r /var/www/html/

Erklärungen
Sektion [Service]:
ExecStart=”-Befehle werden nur ausgeführt, nachdem sich alle “ExecStartPre=”-Befehle erfolgreich beendet haben. Zuerst wird die Datei /var/www/changed auf 0-Bite zurückgesetzt und danach der Rest ausgeführt.

Zusätzliche service-Unit anlegen

Da die .path-Unit Verzeichnisse nicht rekursiv überwachen kann, benötigen wir für unser Beispiel eine zusätzliche .service-Unit. Wir legen die Datei server1-watch.service im Verzeichnis /usr/local/lib/systemd/system/ mit folgendem Inhalt an.

[Unit]
Description=Watching server1 folder.
Before=server1.path
Wants=server1.path

[Service]
Type=forking
ExecStart=inotifywait -dqr -e move,create -o /var/www/changed /var/www/html/

[Install]
WantedBy=multi-user.target

Anmerkung:
Interressant ist, dass systemd intern das inotify-API für .path-Unit verwendet, um Dateisysteme zu überwachen, jedoch deren Rekursiv-Funktion nicht implementiert.

Erklärungen
Die Sektion [Unit]:
Before=” und “Wants=” sind die entsprechenden Korrellationen zu “BindsTo=” und “After=” aus der server1.service-Unit.

Sektion [Service]:
inotifywait protokolliert in die Datei /var/www/changed, die außerhalb von DocumentRoot des Apache-Webservers liegt.

path-Unit eingliedern

Auf Grund der Abhängigkeit gliedern wir zuerst die server1.path-Unit und dann die server1-watch.service-Unit in systemd ein. Die server1.service-Unit benötigt und beinhaltet keine [Install]-Sektion. Bei dem Versuch sie einzugliedern erhielten wir eine Fehlermeldung.

# systemctl enable server1.path
Created symlink /etc/systemd/system/multi-user.target.wants/server1.path /usr/local/lib/systemd/system/server1.path.

# systemctl enable server1-watch.service
Created symlink /etc/systemd/system/multi-user.target.wants/server1-watch.service /usr/local/lib/systemd/system/server1-watch.service.

Nun ist das Monitoring auch gleich aktiv, wie uns die Statusausgaben aller drei Units zeigen.

# systemctl status server1-watch.service
● server1-watch.service - Watching server1 folder.
     Loaded: loaded (/usr/local/lib/systemd/system/server1-watch.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2021-02-21 19:25:20 CET; 1min 49s ago
    Process: 23788 ExecStart=inotifywait -dqr -e move,create -o /var/www/changed /var/www/html/ (code=exited, status=0/SUCCESS)
   Main PID: 23790 (inotifywait)
      Tasks: 1 (limit: 2322)
     Memory: 216.0K
        CPU: 5ms
     CGroup: /system.slice/server1-watch.service
             └─23790 inotifywait -dqr -e move,create -o /var/www/changed /var/www/html/

Feb 21 19:25:20 lap1 systemd[1]: Starting Watching server1 folder....
Feb 21 19:25:20 lap1 systemd[1]: Started Watching server1 folder..

# systemctl status server1.path
● server1.path - Monitoring "changed" file!
     Loaded: loaded (/usr/local/lib/systemd/system/server1.path; enabled; vendor preset: enabled)
     Active: active (waiting) since Sun 2021-02-21 19:25:20 CET; 3min 27s ago
   Triggers: ● server1.service

Feb 21 19:25:20 lap1 systemd[1]: Started Monitoring "changed" file!.

# systemctl status server1.service
● server1.service - Change permissions in server1 folder
     Loaded: loaded (/usr/local/lib/systemd/system/server1.service; static)
     Active: inactive (dead)
TriggeredBy: ● server1.path

Der Status “Active: inactive (dead)” der letzten Ausgabe ist der normale Zustand für die Unit server1.service, denn diese Unit ist nur dann aktiv, wenn sie von server1.path angestoßen wurde ihre Befehlskette auszuführen. Danach geht sie wieder in den inaktiven Zustand über.

service-Unit manuell ausführen

Sollte es einmal hilfreich oder nötig sein die Dateirechte in DocumentRoot des Apache-Webservers manuell zu ändern, setzen wir einfach diesen Befehl ab:

# systemctl start server1.service

Eine erneute Statusabfrage generiert zusätzlich einige Protokollzeilen, denen wir den erfolgreichen Durchlauf der Befehlskette entnehmen können.

# systemctl status server1.service
● server1.service - Change permissions in server1 folder
     Loaded: loaded (/usr/local/lib/systemd/system/server1.service; static)
     Active: inactive (dead) since Mon 2021-02-22 17:55:36 CET; 1min 43s ago
TriggeredBy: ● server1.path
    Process: 2822 ExecStartPre=truncate -s 0 /var/www/changed (code=exited, status=0/SUCCESS)
    Process: 2823 ExecStart=chown -R www-data /var/www/html1/ (code=exited, status=0/SUCCESS)
    Process: 2824 ExecStart=chmod -R g+w /var/www/html1/ (code=exited, status=0/SUCCESS)
    Process: 2825 ExecStart=chmod -R o-r /var/www/html1/ (code=exited, status=0/SUCCESS)
   Main PID: 2825 (code=exited, status=0/SUCCESS)
        CPU: 19ms

Feb 22 17:55:36 lap1 systemd[1]: Starting Change permissions in server1 folder...
Feb 22 17:55:36 lap1 systemd[1]: server1.service: Succeeded.
Feb 22 17:55:36 lap1 systemd[1]: Finished Change permissions in server1 folder.

Quellen systemd-path

Deutsche Manpage ‘systemd.path’

Ein anders gelagertes Beispiel:
PRO-LINUX.DE, Systemd Path Units…

Seite zuletzt aktualisert 2021-06-30