On Wed, 11 Nov 2020 at 09:32:46 +0900, Norbert Preining wrote: > once again, thanks a lot. I have now tried out your suggestion and it > works nicely. Just to make sure, I have now the following units, see > below. I am aware that the system instantiation service onedrive@ is not > optimal since it expects $HOME to be /home/%i, but let us leave this > aside for now. I will document other options like lingering etc.
I still think doing this as a user service (like pulseaudio, gpg-agent, dbus-daemon --session, rygel, flatpak-session-helper, tracker-store, etc.) would be a better approach to use by default: that sort of thing is exactly what `systemd --user` is designed for. Or perhaps it would make sense to have both implementations, like you said you've done, but swap round their enabledness: enable the user service by default, but provide example system units (disabled by default) that can be used by sysadmins who consider the advantages of running this as a system service to outweigh the disadvantages? I assume this package is a FUSE filesystem (or some other daemon) for access to Microsoft OneDrive? It might be useful to compare it with other implementations of the same sort of thing. In GNOME, OneDrive access is not currently implemented (https://gitlab.gnome.org/GNOME/gvfs/-/issues/273); but if it was, it would be a backend for gvfs, which is a collection of user services (gvfs already knows how to access Google Drive, but not OneDrive). One of the motivations for `systemd --user` and the D-Bus "user bus" (which is one per `systemd --user`) was to make services like gvfs available to non-GUI user processes like cron jobs. It looks as though the system service would have to be enabled manually on a per-user basis *anyway*, because the package can't know which users it is meant to be enabled for; so perhaps the best way would be something like this in README.Debian, and arranging the packaging so that it becomes true: onedrive.service is run as a per-user systemd service for each logged-in user by default. Individual users can disable or enable the service for themselves only, by running one of these commands: $ systemctl --user disable onedrive.service $ systemctl --user enable onedrive.service The system administrator can control whether the service is run by default for users who have not explicitly disabled or enabled it by running one of these commands: # systemctl --user --global disable onedrive.service # systemctl --user --global enable onedrive.service It is also possible to run onedrive as a system-level service on behalf of particular users. [explain here why you might want to do that] For example, if a system-level instance of onedrive should run for user "norbert", the system administrator would: - disable the per-user service for the user: # runuser -u norbert -- systemctl --user disable onedrive.service - then enable a system service that runs as that user instead: # systemctl enable onedrive@norbert.service > /lib/systemd/system/onedrive@.service > -------------------------------------- ... > After=network-online.target > Wants=network-online.target > PartOf=onedrive.target > > [Service] > ExecStart=/usr/bin/onedrive --monitor --confdir=/home/%i/.config/onedrive If you are sure you want this to be a system service, this looks right. However, as you said, this assumes every user's home directory is /home/${LOGNAME}. It also won't respect the user's ${XDG_CONFIG_HOME} (it assumes the default ~/.config). systemd documents that it sets ${HOME} for system services that have User= (at least in recent-ish versions, I'm not sure how old this feature is), so you could probably do a bit better by using --confdir=${HOME}/.config/onedrive (see systemd.service(5) for full details of how variables introduced by $ are parsed in ExecStart). However, that's still making an assumption about ${XDG_CONFIG_HOME}. More generally, any per-user environment variables that have been set for the user won't be set for system services that happen to run as the same uid, which could lead to unexpected results. For example, if users set PATH, XDG_CACHE_HOME, XDG_CONFIG_HOME or LANGUAGE, nothing that onedrive does will respect those environment variables. If onedrive wants to access the D-Bus session bus, for example to send notifications, it also won't be able to do that reliably (but it could if it was a user service). For the system service approach, you'll also need a target /lib/systemd/system/onedrive.target. If you *don't* give the target an [Install] section: # /lib/systemd/system/onedrive.target [Unit] Description=OneDrive clients Documentation=... # end of file but instead give onedrive@.service a Wants on it: # /lib/systemd/system/onedrive@.service [Unit] ... After=network-online.target Wants=network-online.target onedrive.target then it will automatically become part of system boot if and only if at least one instance of onedrive@.service is enabled, which I think is probably the right thing to do. > /usr/lib/systemd/user/onedrive.service > -------------------------------------- ... > After=network-online.target > Wants=network-online.target > PartOf=onedrive.target These will not have any effect (unless you have created a /usr/lib/systemd/user/onedrive.target that is not visible here, but that would be pointless because there's only one onedrive.service on the per-user instance). systemd as pid 1 and `systemd --user` are separate service managers, with entirely separate ecosystems of units: neither can see units that were configured for the other. smcv