Closed IOOOTAlan closed 6 years ago
Interesting, I have never thought of anyone trying to change the default runlevel. As docker targets are generally "multi-user" they are trying to go for "graphical" ?
Anyway, if you like to then you can also provide a patch / pull request so that the idea gets attached to your effort and testing.
According to tecmint, one should also implement "isolate".
https://www.tecmint.com/change-runlevels-targets-in-systemd/
Other than that, the systemctl.py does already have a notion of a "self._default_target" that is used throughout the code. However, it is not enough to simply put the value of a "set-default" into that variable as the value is gone as soon as the systemctl.py call is done. To make it permanent one would have to create a file-location with the value and one would have to watch for the reboot time just like for status files now. May be one could abuse the status-file system for something like an init.service - which is something that I had in the planning for quite a time in order to ask the zombie-reaper for its status.
Interesting, I have never thought of anyone trying to change the default runlevel. As docker targets are generally "multi-user" they are trying to go for "graphical" ?
Well, my use case is a little different: I'm using docker-systemctl-replacement in a chroot environment, where I'm setting up a complete root filesystem for creating an image for an embedded device.
As I cannot run the chroot using the ideal systemd-nspawn
because systemd is totally absent from my host or could not be usable in a CI setup, I have to manage those systemctl
calls performed by various package postinstall scripts some way or another, ideally without having to patch every postinst script to make it work in my setup. Your project seems a good solution for my needs, although I don't need to really run any service in my chroot environment, while I just need to persist any filesystem changes related to service enablement/masking etc. performed by systemctl.
Anyway, if you like to then you can also provide a patch / pull request so that the idea gets attached to your effort and testing.
I'm not really that skilled in python development and, as just explained, for my use case I don't really need a full blown implementation of the missing parts in docker-systemctl-replacement. However, If I find the time during my free time (this is a work account), this implementation could be a good exercise in python programming. No promises, though :wink:
I have implemented the runlevel behaviour by create a symlink "default.target". That's actually what the real systemd's systemctl does as well.
However, the "system default" startup command does not check for that at the moment. Nor any other function.
test_1201 test_1211
Did you test it?
As a result, I'll keep the behaviour the upcoming version 1.4, so that systemctl.py does not check the runlevel all by itself.
Hi,
I ran a few tests on this feature by testing it alongside the original implementation. Here are my findings:
systemctl.old
is the original systemctl binary):# ls -l /lib/systemd/system/default.target
lrwxrwxrwx 1 root root 16 Jul 30 21:31 /lib/systemd/system/default.target -> graphical.target
# ls -l /etc/systemd/system/default.target
ls: cannot access '/etc/systemd/system/default.target': No such file or directory
# systemctl get-default
multi-user.target
# systemctl.old get-default
graphical.target
set-default
command does not error out when run without an actual target
argument:# systemctl set-default
#
set-default
command seems to not be able to actually set the default target to any existing target unit:# find / -name \*.target
/usr/lib/systemd/user/exit.target
/usr/lib/systemd/user/sockets.target
/usr/lib/systemd/user/paths.target
/usr/lib/systemd/user/graphical-session.target
/usr/lib/systemd/user/smartcard.target
/usr/lib/systemd/user/shutdown.target
/usr/lib/systemd/user/printer.target
/usr/lib/systemd/user/busnames.target
/usr/lib/systemd/user/basic.target
/usr/lib/systemd/user/timers.target
/usr/lib/systemd/user/graphical-session-pre.target
/usr/lib/systemd/user/default.target
/usr/lib/systemd/user/bluetooth.target
/usr/lib/systemd/user/sound.target
/etc/systemd/system/multi-user.target.wants/remote-fs.target
/lib/systemd/system/reboot.target
/lib/systemd/system/multi-user.target.wants/getty.target
/lib/systemd/system/local-fs-pre.target
/lib/systemd/system/exit.target
/lib/systemd/system/rpcbind.target
/lib/systemd/system/mail-transport-agent.target
/lib/systemd/system/sockets.target
/lib/systemd/system/suspend.target
/lib/systemd/system/initrd-switch-root.target
/lib/systemd/system/local-fs.target
/lib/systemd/system/network.target
/lib/systemd/system/paths.target
/lib/systemd/system/initrd-fs.target
/lib/systemd/system/initrd.target
/lib/systemd/system/final.target
/lib/systemd/system/cryptsetup-pre.target
/lib/systemd/system/smartcard.target
/lib/systemd/system/runlevel0.target
/lib/systemd/system/shutdown.target
/lib/systemd/system/remote-fs.target
/lib/systemd/system/network-online.target
/lib/systemd/system/emergency.target
/lib/systemd/system/network-pre.target
/lib/systemd/system/nss-lookup.target
/lib/systemd/system/runlevel5.target
/lib/systemd/system/sigpwr.target
/lib/systemd/system/slices.target
/lib/systemd/system/hybrid-sleep.target
/lib/systemd/system/runlevel1.target
/lib/systemd/system/printer.target
/lib/systemd/system/kexec.target
/lib/systemd/system/busnames.target
/lib/systemd/system/poweroff.target
/lib/systemd/system/remote-fs-pre.target
/lib/systemd/system/halt.target
/lib/systemd/system/runlevel3.target
/lib/systemd/system/basic.target
/lib/systemd/system/getty.target
/lib/systemd/system/cryptsetup.target
/lib/systemd/system/timers.target
/lib/systemd/system/hibernate.target
/lib/systemd/system/initrd-root-fs.target
/lib/systemd/system/swap.target
/lib/systemd/system/sleep.target
/lib/systemd/system/runlevel6.target
/lib/systemd/system/runlevel2.target
/lib/systemd/system/rescue.target
/lib/systemd/system/nss-user-lookup.target
/lib/systemd/system/default.target
/lib/systemd/system/bluetooth.target
/lib/systemd/system/time-sync.target
/lib/systemd/system/graphical.target
/lib/systemd/system/ctrl-alt-del.target
/lib/systemd/system/multi-user.target
/lib/systemd/system/sysinit.target
/lib/systemd/system/umount.target
/lib/systemd/system/runlevel4.target
/lib/systemd/system/sound.target
/lib/systemd/system/system-update.target
/lib/systemd/system/sysinit.target.wants/cryptsetup.target
# systemctl set-default runlevel4.target
ERROR:systemctl:no such runlevel /etc/systemd/system/runlevel4.target
# systemctl.old set-default runlevel4.target
Created symlink /etc/systemd/system/default.target, pointing to /lib/systemd/system/multi-user.target.
# systemctl set-default sleep.target
ERROR:systemctl:no such runlevel /etc/systemd/system/sleep.target
# systemctl.old set-default sleep.target
Removed symlink /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target, pointing to /lib/systemd/system/sleep.target.
# systemctl set-default multi-user.target
ERROR:systemctl:no such runlevel /etc/systemd/system/multi-user.target
# systemctl.old set-default multi-user.target
Removed symlink /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target, pointing to /lib/systemd/system/multi-user.target.
Thanks a lot for testing. I found that systemctl.py had not been using the existing *.target files for the list of possible targets, so that may be responsible for some irritations. Actualy, inside a docker container a lot of targets are missing, so I had added a static (hard coded) list of targets to be sure that some basic commands do work.
In any case, when doing "systemctl set-default basic.target" you will see that it binds to some /usr/lib path by now.
Created symlink from /home/guidod/docker/docker-systemctl-replacement/tmp/tmp.test_1211/root/etc/systemd/system/default.target -> /usr/lib/systemd/system/basic.target
Support for the
get/set-default
commands is currently missing.This is their intended function:
I currently needed the
set-default
command to not error-out during a post-install script execution, so I merely added an emptyset_default_modules
function to theSystemctl
class, like this:and was able to proceed further.