This still doesn’t put away that this is a hack
I’ve said already above that something like this would be possible but not to be preferred in my mind. The main thing I don’t like is that we’re crossing layers here from the bottom to the top. Todays Linux desktop systems are build in a way that nothing calls into directly into a user session instance. See the references I gave above. In every case where such a bottom-up call is needed an agent-style like approach is chosen to avoid the direct call and delegate the execution to something inside the user-session. The key principle here is that the user session has the responsibility to decide if it wants to register a handler or not. We move this decision now into the system part.
The example @mvo gave is quite nice as it shows what is possible with todays systems but it has a fundamental problem. If the URI we hand to xdg-open
requires a program to start which is either not able to accept open requests while already running or doesn’t run yet inside the user session the new process spawned by systemd-run
is placed incorrect in the process hierarchy of the system. I did a quick experiment:
# Get out of my current session and into a new one
$ ssh simon@localhost
# Get a root shell without any environment leaking from the user
localhost$ env -i sudo -i
localhost$ systemd-run --scope --uid=1000 --setenv=DISPLAY=:0 --setenv=XAUTHORITY=/home/simon/.Xauthority /usr/bin/xdg-open https://forum.snapcraft.io
That opens up the browser running with the specified user (uid 1000) and shows the webpage. However the process hierarchy now looks like this:
systemd─┬
├─sshd───sshd───sshd───zsh───sudo───bash───firefox─┬─{Cache I/O}
│ ├─{Cache2 I/O}
│ ├─{Compositor}
[...]
That isn’t really what we want. Using something like
localhost$ systemd-run --slice user-1000.slice --uid=1000 --setenv=DISPLAY=:0 --setenv=XAUTHORITY=/home/simon/.Xauthority /usr/bin/xdg-open https://forum.snapcraft.io
helps a bit but still leaves firefox
as a child of system systemd
process.
systemd─┬─ModemManager─┬─{gdbus}
│ └─{gmain}
├─NetworkManager─┬─dhclient
│ ├─dnsmasq
│ ├─{gdbus}
│ └─{gmain}
├─accounts-daemon─┬─{gdbus}
│ └─{gmain}
├─acpid
├─2*[agetty]
├─apt-cacher-ng───2*[{apt-cacher-ng}]
├─atd
├─avahi-daemon───avahi-daemon
├─bluetoothd
├─canonical-livep───14*[{canonical-livep}]
├─cgmanager
├─colord─┬─{gdbus}
│ └─{gmain}
├─cron
├─cups-browsed─┬─{gdbus}
│ └─{gmain}
├─cupsd───2*[dbus]
├─dbus-daemon
├─2*[dnsmasq]
├─dockerd─┬─containerd───8*[{containerd}]
│ └─14*[{dockerd}]
├─firefox─┬─{Cache I/O}
│ ├─{Cache2 I/O}
│ ├─{Compositor}
[...]
├─lightdm─┬─Xorg
│ ├─lightdm─┬─upstart─┬─thunderbird
[...]
In the process tree we really want to have the launched process below lightdm──upstart
(Ubuntu 16.04).
Also this behavior is expected as described in the man page of systemd-run
:
If a command is run as transient service unit, it will be started and managed by the service manager like any
other service, and thus shows up in the output of systemctl list-units like any other unit. It will run in a
clean and detached execution environment, with the service manager as its parent process. In this mode,
systemd-run will start the service asynchronously in the background and return after the command has begun
execution.
The --user
option for systemd-run can’t be used as not all systems we support use systemd --user
to manage user sessions (Ubuntu 16.04 being the best example).
So using systemd-run
is not a real option to solve the problem we’re discussing here. As described before we need something inside the user session, below the user session init manager in the process tree which can start a process at the right place in the tree. That is what snapd-xdg-open
did or a snapd --user
would do. As far as I know there is no way to inject a process into the tree from the outside and if that exists it would be a much more uglier hack.
The other option would be to add support for multiple init systems used for user sessions (upstart, system, …) into snapd but I don’t think that is a real option as we defended adding support for upstart before for system services.
I hope this describes my concerns a bit better to help driving the discussion towards an agreement.