[systemd-devel] Packaging systemd user-instance service files
Ahmed S. Darwish
darwish.07 at gmail.com
Fri Jul 17 17:44:22 PDT 2015
Hi Mantas,
On Sat, Jul 18, 2015 at 12:17:51AM +0300, Mantas Mikulėnas wrote:
> On Fri, Jul 17, 2015 at 9:38 PM, Ahmed S. Darwish <darwish.07 at gmail.com>
> wrote:
>
> > Hi everyone,
> >
> > I'm currently transforming a network daemon to become a native
> > ``Type=notify'' systemd service. This daemon uses native PulseAudio
> > simple APIs for output.
> >
> > Due to the PulseAudio dependency, the service needs to run under the
> > user session. Otherwise, all PulseAudio APIs [e.g. pa_simple_new()]
> > returns a ``Connection Refused'' error. [1]
> >
> > Given the above, I've built the following service file:
> >
> > [Unit]
> > Description=AirTunes Synchronous Audio Service
> > [Service]
> > Type=notify
> > ExecStart=/usr/local/bin/shairport-sync
> > [Install]
> > WantedBy=default.target
> >
> > And the following snippet in the package Makefile.am:
> >
> > cp scripts/shairport-sync.service /usr/lib/systemd/user/
> > systemctl --user daemon-reload
> > systemctl --user enable shairport-sync.service
> > systemctl --user start shairport-sync.service
> >
>
> So the real problem is not that it *doesn't work*, but rather that
> it *shouldn't be done*. That makefile is mixing entirely separate
> things – installation (packaging), global configuration, and
> per-user configuration.
>
This is a small github project, and you have to handle the
standard `./confugre', `make' and `sudo make install' sequence
out of the box. There's no fancy Debian or Fedora packages for
it even yet.
The per-use configuration part was forced upon us due to our
dependency on native PulseAudio APIs; APIs which do not work
except when our daemon is run from the same session PulseAudio
is running from.
> (Not to mention the dangerous assumptions that 1) there's exactly
> one user logged in during installation, and 2) that they'll
> actually want to run the program right now...)
>
Yes, `systemctl --user' is wrong and specific only to the current
user, but that's why I was asking for an alernative, more generic,
solution that will fit all users in the first place :-)
> > As you can see, the service is properly installed under
> > ``/usr/lib/systemd/user/'' to run under the systemd user instance.
> >
> > Now the problem is that the Makefile commands above run as root,
> > and thus all the ``systemctl --user'' commands fail with:
> >
> > Failed to get D-Bus connection: Connection refused
> >
> > So, the question is, can I start ``systemctl --user daemon-reload''
> > and ``systemctl --user enable'' above in some form while the
> > Makefile is run from root?
> >
>
> No, but you don't need to. Just install the file to /usr/lib/systemd/user,
> and that's it. It'll be available to all users.
>
> If you want to forcefully enable the service for all users, then also
> symlink it into /usr/lib/systemd/user/default.target.wants/, which is
> almost exactly what `systemctl enable` does (except system-wide).
> That'll make it start on login for everyone.
>
Excellent! `systemctl --user enable' always did the symbolic
link under `$HOME/.config/systemd/user/'; I mistakenly thought
that it must be done _only_ this way for each and every user.
Now I understand; it seems it was done that way just not to affect
other users of the system. It couldn't be done any other way due
to the system permissions of /usr/lib/systemd/user
> But the general rule is, do not start user-session processes from system
> tasks.
Having the service installed `per-user' was something that was
unfortunately forced. I will still inspect what will happen when
two logged-in users lead to two instances of the daemon running :-(
Can we disable multiple instances of the daemon in a systemd-native
way, even when the service is run per user? Yes, this question
implies a possible problem in the design, but again, having the
service per-user is the only choice we have so far.
Thanks a lot Mantas for your help!
Regards,
Darwish
More information about the systemd-devel
mailing list