3 ms·
Nowadays, creating a raw chroot is far from simple. Last time I tried, I had to handle the special mount points like /proc and /sys. I can't remember the detail
by idoubtit 7y ago
Nowadays, creating a raw chroot is far from simple. Last time I tried, I had to handle the special mount points like /proc and /sys. I can't remember the details, but I believe there were other problems.
In my experience, systemd-nspawn provides a nice alternative. It's mainly a chroot that abstracts the low-level details, and it fixes some security concerns (with cgroups, etc) and adds some nice features: e.g. networking, or `systemctl status` from the host that will display the sub-tree for the processes of the sub-host.
- znpy 7y agoLast time I tried to recover an ubuntu system by booting from a live sub, mounting the drive and chrooting into the target device i was surprised to find out that systemd refuses to work if it detects being run in a chroot. I was left puzzled.
- Spivak 7y agoIf you're talking about what happens when you mount the root filesystem, chroot into it, and run systemctl then you're essentially asking to break out of the chroot and communicate to the service manager outside the chroot which almost always doesn't make sense. The only time this is reasonable is when a container needs to manage services on the host a la what Portainer does for Docker. You have a lot of options for accomplishing what you want. * To run a service with a given root filesystem add RootFilesystem=/path to your unit file. * Run a service from an image of a root filesystem use systemd portable services. * To run your service using the init system in your root filesystem (could be systemd but doesn't have to be) use systemd-nspawn --boot.
- znpy 7y agoyou know, I just wanted to run services from within the chroot, like you could do in the pre-systemd era. I mean, as long as you have /proc, /sys and etc bind-mounted you should be okay, right ?
- Spivak 7y agoRight, but what you're describing as running a pre-systemd "service" is really just "run a shell script that sources some environment files and then double forks". Running a systemd service means talking to the /org/freedesktop/systemd1 object on the system bus typically listening on /run/dbus/system_bus_socket and asking it to start your service. This is all that systemctl really does. mkdir ./rootfs curl -O https://cloud-images.ubuntu.com/minimal/releases/bionic/release/ubuntu-18.04-minimal-cloudimg-amd64-root.tar.xz | tar -xJPC ./rootfs mount -o bind /proc ./rootfs/proc mount -o bind /sys ./rootfs/sys mkdir ./rootfs/run/dbus mkdir ./rootfs/run/systemd mount -o bind /run/dbus ./rootfs/dbus mount -o bind /run/systemd ./rootfs/systemd chroot ./rootfs bash # See that it works just by sending dbus messages. dbus-send --system --print-reply --type=method_call --dest=org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager.ListUnits # Now do the same with systemctl. export SYSTEMD_IGNORE_CHROOT=true systemctl list-units THIS IS ALMOST CERTAINLY NOT WHAT YOU WANT. You're just talking to the host systemd. You won't see any of the services in your chroot since how could systemd know about them? Your chrooted root is also now just root on the host. Just use systemd-nspawn. # undo all the bind mount junk. chroot ./rootfs bash useradd ubuntu -G sudo passwd ubuntu exit cd ./rootfs systemd-nspawn -x --private-network --boot # login sudo systemctl list-units
- zymhan 7y agoThis was very informative, thank you.
- streb-lo 7y agoNothing a shell script wrapper can't setup for you -- arch linux provides an arch-chroot which handles exactly that.