systemd: problem z uprawnieniami dla mkdir i ExecStartPre

37

Mam problem z tym (skróconym) plikiem usługi systemd:

[Unit]
Description=control FOO daemon
After=syslog.target network.target

[Service]
Type=forking
User=FOOd
Group=FOO
ExecStartPre=/bin/mkdir -p /var/run/FOOd/
ExecStartPre=/bin/chown -R FOOd:FOO /var/run/FOOd/
ExecStart=/usr/local/bin/FOOd -P /var/run/FOOd/FOOd.pid
PIDFile=/var/run/FOOd/FOOd.pid

[Install]
WantedBy=multi-user.target

Niech FOOd będzie nazwą użytkownika, a FOO nazwą grupy, która już istnieje dla mojego demona /usr/local/bin/FOOd.

Muszę utworzyć katalog /var/run/FOOd/przed uruchomieniem procesu demona /usr/local/bin/FOOdza pośrednictwem # systemctl start FOOd.service. To się nie udaje, ponieważ mkdir nie może utworzyć katalogu z powodu uprawnień:

...
Jun 03 16:18:49 PC0515546 mkdir[2469]: /bin/mkdir: cannot create directory /var/run/FOOd/: permission denied
Jun 03 16:18:49 PC0515546 systemd[1]: FOOd.service: control  process exited, code=exited status=1
...

Dlaczego mkdir nie działa w ExecStartPre i jak mogę to naprawić? (I nie, nie mogę używać sudo dla mkdir ...)

Matt
źródło
FYI: Używam Debian 8
Matt
Czy możesz przetłumaczyć komunikat o błędzie na angielski?
Thushi,
1
... Jun 03 16:18:49 PC0515546 mkdir [2469]: / bin / mkdir: katalog / var / run / FOOd / nie można utworzyć: brak uprawnień Jun 03 16:18:49 PC0515546 systemd [1] : FOOd.service: proces kontroli zakończony, kod = status zakończony = 1 ...
Matt

Odpowiedzi:

56

Musisz dodać

PermissionsStartOnly=true

do [Service]. Twój użytkownik FOOdoczywiście nie jest upoważniony do utworzenia katalogu w /var/run. Aby zacytować stronę podręcznika:

Przyjmuje argument boolowski. Jeśli true, opcje wykonania związane z uprawnieniami, skonfigurowane z opcją User = i podobnymi opcjami (zobacz systemd.exec (5), aby uzyskać więcej informacji), są stosowane tylko do procesu rozpoczętego przez ExecStart =, a nie do różnych innych ExecStartPre = Polecenia, ExecStartPost =, ExecReload =, ExecStop = i ExecStopPost =. W przypadku wartości false ustawienie jest stosowane do wszystkich skonfigurowanych poleceń w ten sam sposób. Domyślnie false.

embik
źródło
1
Cudownie, dokładnie to, czego szukałem.
Robert
2
Ta opcja powoduje, że polecenia są ExecReload=uruchamiane z uprawnieniami administratora. To może nie być to, czego chcesz.
Rockallite,
@Rockallite, tak dosłownie mówi cytowana dokumentacja: tak.
embik
2
PermissionsStartOnlybył przestarzały. Odniesienie: github.com/NixOS/nixpkgs/issues/53852 Jak to zrobić teraz?
adrelanos
2
@ adrelanos Teraz dodaj +natychmiast po ExecStartPre=. Na przykładExecStartPre=+/bin/mkdir test
Jamie Scott
28

To nie jest odpowiedź, która wyjaśnia lub rozwiązuje problem z uprawnieniami, ale myślę, że powinieneś po prostu użyć opcji systemds RuntimeDirectory. Cytując stronę podręcznika :

RuntimeDirectory=, RuntimeDirectoryMode=
       Takes a list of directory names. If set, one or more directories by
       the specified names will be created below /run (for system
       services) or below $XDG_RUNTIME_DIR (for user services) when the
       unit is started, and removed when the unit is stopped. The
       directories will have the access mode specified in
       RuntimeDirectoryMode=, and will be owned by the user and group
       specified in User= and Group=. Use this to manage one or more
       runtime directories of the unit and bind their lifetime to the
       daemon runtime. The specified directory names must be relative, and
       may not include a "/", i.e. must refer to simple directories to
       create or remove. This is particularly useful for unprivileged
       daemons that cannot create runtime directories in /run due to lack
       of privileges, and to make sure the runtime directory is cleaned up
       automatically after use. For runtime directories that require more
       complex or different configuration or lifetime guarantees, please
       consider using tmpfiles.d(5).

Wystarczy zatem zmienić plik usługi na:

[Unit]
Description=control FOO daemon
After=syslog.target network.target

[Service]
Type=forking
User=FOOd
Group=FOO
RuntimeDirectory=FOOd
RuntimeDirectoryMode=$some-mode
ExecStart=/usr/local/bin/FOOd -P /run/FOOd/FOOd.pid
PIDFile=/run/FOOd/FOOd.pid

[Install]
WantedBy=multi-user.target
Wieland
źródło
Dziękuję dziękuję. Niestety brakuje w pakiecie OpenVPN Ubuntu !!
BaseZen