Skip to content

Support systemd user units/services #7

Open
pmenzel opened this issue Apr 26, 2019 · 5 comments
Open

Support systemd user units/services #7

pmenzel opened this issue Apr 26, 2019 · 5 comments

Comments

@pmenzel
Copy link
Contributor

pmenzel commented Apr 26, 2019

From the ArchWiki:

systemd offers users the ability to manage services under the user's control with a per-user systemd
instance, enabling users to start, stop, enable, and disable their own units.

To avoid cluttering /etc/systemd/system with unit files for specific projects, it’d be nice if unit files from within the project could be started/enabled.

$ grep '\.service' /etc/mxstartups
baucamhttpd     cu   root baucamhttpd.service
getcams         cu   root getcams.service
tonerlow        argh root	tonerlow-cupsd.service                     tonerlow[80:631]

From systemd.unit(5):

   User Unit Search Path
       ~/.config/systemd/user.control/*
       $XDG_RUNTIME_DIR/systemd/user.control/*
       $XDG_RUNTIME_DIR/systemd/transient/*
       $XDG_RUNTIME_DIR/systemd/generator.early/*
       ~/.config/systemd/user/*
       /etc/systemd/user/*
       $XDG_RUNTIME_DIR/systemd/user/*
       /run/systemd/user/*
       $XDG_RUNTIME_DIR/systemd/generator/*
       ~/.local/share/systemd/user/*
       ...
       /usr/lib/systemd/user/*
       $XDG_RUNTIME_DIR/systemd/generator.late/*
@donald
Copy link
Contributor

donald commented Apr 26, 2019

A user unit would require a user manager( systemd --user) to be running. The systemds way to start a user manager after boot would be via loginctlctl enable-linger USER. But I guess you could as well add user@UID.service to mxstartups and start a user manager via mxstartupctl this way, too.

The user manager would start any services enabled by the user ( config in ~USER/.config/systemd/user ). This is tricky, because just enabling a service for a user would start the service on every machine, the user logs in (and starts a user manager for the session). You'd have to use something like ConditionHost= in the service file but that would be redundant with the host information from mxstartup.

The other option would be not to enable the service for the user, but call something like systemctl --user start service . However, I don't know how to do that for another users.

@pmenzel
Copy link
Contributor Author

pmenzel commented Apr 26, 2019

A user unit would require a user manager( systemd --user) to be running. The systemds way to start a user manager after boot would be via loginctlctl enable-linger USER. But I guess you could as well add user@UID.service to mxstartups and start a user manager via mxstartupctl this way, too.

We already built our systemd package with -Ddefault-kill-user-processes=false.

https://github.molgen.mpg.de/mariux64/bee-files/blob/2995af5a342ceee0a8ec78e6b95f53cfc39f2b35/systemd.be0#L74

So, the loginctl command is not needed.

The user manager would start any services enabled by the user (config in ~USER/.config/systemd/user). This is tricky, because just enabling a service for a user would start the service on every machine, the user logs in (and starts a user manager for the session). You'd have to use something like ConditionHost= in the service file but that would be redundant with the host information from mxstartup.

The other option would be not to enable the service for the user, but call something like systemctl --user start service . However, I don't know how to do that for another users.

I was thinking about the last option, because we still use mxstartup. I thought the user name can be specified in /etc/mxstartups, so the services would be run under that username.

@donald
Copy link
Contributor

donald commented Apr 26, 2019

We already built our systemd package with -Ddefault-kill-user-processes=false.

So, the loginctl command is not needed.

Yes, but you still need to start the user manager on system boot.

I was thinking about the last option, because we still use mxstartup. I thought the user name can be specified in /etc/mxstartups, so the services would be run under that username.

I don't know, from where systemd --user picks up the username. It looks like it doesn't just the uid of the caller, because it oesn't work with sudo. So I guess it wouldn't work out of the box with mxstartups which, I think, uses su. Someone needs to look in the sources.

@donald
Copy link
Contributor

donald commented May 1, 2019

more or less getuid() and getpwuid() ... Should work with su

@donald
Copy link
Contributor

donald commented May 6, 2019

This works:

#! /usr/bin/bash
user="molgen"
uid=$(id -u $user)
systemctl start user@$uid
XDG_RUNTIME_DIR=/run/user/$uid setuid $uid systemd-run --user --unit testservice1 sleep 1000
XDG_RUNTIME_DIR=/run/user/$uid setuid $uid systemctl --user start testservice2
XDG_RUNTIME_DIR=/run/user/$uid setuid $uid systemctl --user status

Where testservice2 is defined (not not enabled!) by the user in
~molgen/.config/systemd/user/testservice2.service :

[Service]
ExecStart=sleep 1000

One problem here might be, that systemctl start user@$uid would wait for the user manger to be started and we have bad experience with calling systemctl start from within mxstartup. This is assumed to deadlock now and then. If we added '--no-block' , we couldn't talk to the user manager.....

'systemctl start testservice2should better go into a project startstop script. However,systemctl start user@$uid` talks to pid 1, this can't be done by the project user....

Hmmm.....

Sign in to join this conversation on GitHub.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants