Jak sprawić, aby moja usługa systemowa była uruchamiana przez określonego użytkownika i zaczynała się przy rozruchu?

132

Właśnie zaktualizowałem serwer Ubuntu 14 do wersji 15. Miałem problem z uruchomieniem skryptu upstart po aktualizacji i przeczytałem, że systemd jest nowym domyślnym. Nie jestem ekspertem od Linuksa, więc proszę, uspokój się :-)

Oto, czym był mój skrypt wstępny:

description "NZBGet upstart script"

setuid robert
setgid robert

start on runlevel [2345]
stop on runlevel [016]

respawn

expect fork

script
    exec nzbget -D
end script

pre-stop script
    exec nzbget -Q
end script

Opierając się na stronie wiki upstart do systemd , użyłem podanych tam tabel, aby zmapować rzeczy tak dokładnie, jak to możliwe w moim nowym pliku usługi systemd:

[Unit]
Description=NZBGet Service

[Service]
Type=forking
ExecStart=/usr/local/bin/nzbget -D
ExecStop=/usr/local/bin/nzbget -Q
Restart=on-failure

Ten plik znajduje się na stronie /home/robert/.config/systemd/user/nzbget.service. Aby ręcznie uruchomić usługę, robiłem:

$ systemctl --user start nzbget

To działa świetnie. Jednak po wylogowaniu z sesji SSH usługa zostaje wyłączona. Ponadto nie uruchamia się podczas uruchamiania lub logowania użytkownika. Chcę, aby zachowywał się tak samo, jak w przypadku usługi upstart: chcę, aby uruchamiał się przy rozruchu, działał nieprzerwanie i jako określony użytkownik.

Co muszę zrobić, aby uzyskać tę konfigurację?

void.pointer
źródło

Odpowiedzi:

163

Pierwszy problem

Możesz określić dyrektywy User=oraz Group=w [Service]sekcji pliku jednostkowego.

Drugi problem

Aby usługa działała podczas rozruchu, nie należy umieszczać jej w folderze domowym. Zamiast tego, włóż to pod /etc/systemd/system/. Jest to folder przeznaczony do wykorzystania przez administratora systemu (tj. Ciebie) w celu dodania nowych usług ogólnosystemowych.

Inne foldery obejmują:

  • /usr/lib/systemd/system/jest przeznaczony dla pakietów, które chcą instalować pliki jednostek, choć w Debianie i Ubuntu folder jest tak naprawdę, /lib/systemd/system/ponieważ różne foldery bini libfoldery nie zostały jeszcze połączone w zunifikowany /usr/prefiks.
  • /usr/local/systemd/system/ służy do instalowania jednostek przez lokalnie skompilowane pakiety.

Testowanie urządzenia

Gdy plik jednostki znajdzie się w odpowiednim miejscu, możesz spróbować uruchomić jednostkę natychmiast, wpisując systemctl start <UNIT_FILENAME>jak zwykle. Powinien działać bez konieczności wpisywania pełnej ścieżki urządzenia. Nie trzeba też określać rozszerzenia, jeśli jest .service.

Włączanie urządzenia

Zanim będzie można włączyć urządzenie, należy dodać [Install]sekcję, w której należy dodać dyrektywę WantedBy=multi-user.target. Niniejsza dyrektywa określa etap procesu rozruchu, podczas którego usługa powinna zostać uruchomiona (jeśli została włączona). multi-user.targetjest odpowiedni dla większości usług.

Po dodaniu tych informacji można użyć systemctl enable <UNIT_FILENAME>, co umożliwia włączenie urządzenia, dzięki czemu systemd będzie odtąd automatycznie uruchamiany podczas uruchamiania na określonym etapie.

Yamaho
źródło
To zadziałało. Musiałem jednak podać bezwzględną ścieżkę do nazwy pliku usługi w systemctl enablepoleceniu, na początku nie było to dla mnie oczywiste. Również włączenie dało mi ostrzeżenie o brakującej [Install]sekcji. Zignorowałem to, ale nie jestem pewien, czy wpłynie to na jego zdolność do uruchamiania w czasie rozruchu.
void.pointer
2
InstallOstrzeżenie było rzeczywiście bardzo ważne. Nie uruchomi się przy rozruchu bez WantedBy=multi-user.targetpod [Install]sekcją. Po dodaniu do tego .servicepliku, a następnie można enablego.
void.pointer
4
Przepraszam za pozostawienie odpowiedzi bez nadzoru przez tak długi czas. Poprawiłem lokalizację pliku jednostki i dodałem brakujące informacje o [Install]sekcji. Mam nadzieję, że teraz jest to bardziej pomocne dla każdego, kto go szuka.
Yamaho,
5
Staje się to znacznie łatwiejsze, gdy nazwa użytkownika jest szablonowana, tzn. Twoja usługa jest zdefiniowana przy użyciu nazwy pliku w formacie, [email protected]a enabled jak [email protected]ustawienie staje się User=%ioznaczające, że użytkownik nie jest zakodowany na stałe i wielu użytkowników może korzystać z tej samej definicji. Przykład.
Walf
1
Czy zacznie się, jeśli go podłożę /etc/systemd/user/?
Khurshid Alam
46

Być może zainteresuje Cię użycie funkcji systemd do „utrzymywania użytkownika”. Jest włączony przez loginctl enable-linger USERNAME.

Powoduje to uruchomienie osobnego menedżera usług dla danego użytkownika podczas rozruchu, więc jednostki zdefiniowane przez użytkownika ~/.config/systemd/userzostaną pobrane i przetworzone podczas rozruchu i wyłączenia zgodnie z konfiguracją usługi.

Możesz także użyć systemctl --userdo zarządzania usługami i ich konfigurowania, które będą działać na menedżerze usług użytkownika, a nie na systemie.

byteborg
źródło
6
systemctl --userto fantastyczne odkrycie. Dzięki!
Anwar
@byteborg Może możesz przyczynić się do unix.stackexchange.com/questions/409900/… ? Potrzebuję zależności od PostgreSQL w usłudze przeciągania użytkowników, ale baza danych pozostaje usługą systemową, a nie jedną użytkownika.
Michał F,
1
Czy po uruchomieniu usług są jakieś techniki, które mogą pozwolić użytkownikowi zobaczyć dzienniki usługi? Nieuprzywilejowany użytkownik nie będzie mógł uzyskać dostępu do / var / log / syslog.
mpr
2
Pamiętaj jednak, że systemctl --usernie działa to w przypadku sesji SSH.
Mark K Cowan
2
Powinno być przyjęte rozwiązanie
Drew