jupyterhub / systemdspawner

Spawn JupyterHub single-user notebook servers with systemd
BSD 3-Clause "New" or "Revised" License
92 stars 45 forks source link

service_running doesn't account for chroot #90

Open SomeoneSerge opened 2 years ago

SomeoneSerge commented 2 years ago

https://github.com/jupyterhub/systemdspawner/blob/e75caddd7f310c591f642cdd559107c171a1e657/systemdspawner/systemd.py#L158

systemctl is-active outputs a warning and exits with 0 when run in a chroot environment (by "design", to quote the designer), after which jupyterhub attempts to stop a non-existent unit and fails:

Running in chroot, ignoring command 'is-active'
Running in chroot, ignoring command 'stop'
500 GET /hub/spawn (127.0.0.1): Error in Authenticator.pre_spawn_start: Exception Could not stop already existing unit
behrmann commented 2 years ago

Maybe let's step back a bit and ask what it is you'd like to do? :)

The point Lennart makes in the source you link is quite valid, but - depending on what it is you wish to achieve - there's possible patches for systemdspawner. systemd itself provides ample features to make calls to chroot unnecessary (because it does it under the hood; RootDirectory= and friends) or the check above could be amended to also run systemd-detect-virt.

SomeoneSerge commented 2 years ago

If you so wish, but I must warn we'll be going off the point :) I want to run jupyterhub on NixOS and have access to user kernels (e.g. installed via ipykernel from venv or conda environments).

Now,

The workaround I've been using is the one with the namespace (there's a convenience function in nix for that, called buildFHSUserEnv) and it works perfectly fine as long as I:

IIUC, this is rather orthogonal to RootDirectory=

behrmann commented 2 years ago

Oh, this is a very interesting problem and I've been eyeing Nix for Jupyterhub deployments, but haven't yet found the time to get my feet wet with Nix.

I don't know how buildFHSUserEnv jives with this, but isn't there also the problem that libraries in the store have explicitly set RPATHs pointing to other things in the store? I heard this makes using binary packages from other sources (conda, wheels from PyPI) - if not impossible - difficult?

Is my understanding, that currently you are using LocalProcessSpawner and pointing it at a chroot generated with buildFHSUserenv? If so that could, with a bit of hacking on systemdspawner, be moved over. You could then use RootDirectory= to use the same chroot.

Sorry if I'm misunderstanding your setup, my knowledge of Nix is rather rudimentary.

SomeoneSerge commented 2 years ago

@behrmann definitely nothing to be sorry about, and thank you for advancing the discussion:)


But to get back from nix and to the issue at hand, I'd be say to say that:

behrmann commented 2 years ago

I think I know understand your problem better and I learned something, thank you!

While I agree that something like Maybe bool would be a sensible signature for systemctl is-active, it's unfortunately by somewhat limited POSIX semantics (and backwards compatibility), so that won't change. It will probably be difficult and maybe prone to breakage trying to reimplement, although that would surely be possible.

I still think, that RootDirectory= would be the most promising avenue of solving your problem. Can buildFHSUserenv just provide the chroot without doing the actual chrooting via chrootenv? If so you could

behrmann commented 2 years ago

I think the above would be the cleanest solution. If that is not possible there's other possible solutions. The environment variable SYSTEMD_IGNORE_CHROOT will short circuit the chroot test, but I don't know in what other problems you might run, e.g. no dbus in the chroot.

SomeoneSerge commented 2 years ago

Actually, I think d-bus and polkit still work (it's not quite chroot after all), at least I've just tried running d-feet from this sort of a namespace and it didn't fail

Thank you for SYSTEMD_IGNORE_CHROOT! I'll see what happens with that on