9

I need to enable systemd services before I'm actually booting the system (for unattended install purposes). Therefore I can't use systemctl. I could use systemd-nspawn, but I think it not that well suited for scripting.

I know that systemctl creates a symlink, but is that all I have to do and can I do it without 'disturbing' systemd?

This seems to work, but can you confirm it?

ln -s /usr/lib/systemd/system/sshd.service /etc/systemd/system/multi-user.target.wants/sshd.service
5
  • 2
    systemd will read the [Install] Section of the unit file. So ln -s will not always work and have risk of corrupted the system consistency Oct 4, 2018 at 23:19
  • 2
    But you can use systemd-nspawn to boot the installed system as a container and use systemctl --machine Oct 4, 2018 at 23:22
  • Good to know that it can cause issues. I'll update my answer with a warning. So --machine executes the command in the container thats a very good solution.
    – rudib
    Oct 4, 2018 at 23:41
  • @炸鱼薯条德里克 Can you elaborate on the connection between "reading the [Install]" and enabling a service/corrupting? I don't see how these two things relate at all. What exactly happens when systemd read the "Install" section and where do you know it from? I want to learn about it too.
    – donaastor
    Jun 10, 2023 at 8:19
  • @donaastor man7.org/linux/man-pages/man5/… this section describes how the unit should be properly enabled Jul 13, 2023 at 0:23

1 Answer 1

5

How to use systemd-nspawn to enable a service or perform changes on systemd:

tmux new-session -d -s mysession "systemd-nspawn --boot --machine=machine_name -D /install/directory"
systemctl --machine=machine_name enable sshd
machinectl poweroff machine_name

Warning: Just using a symlink may cause issues as systemd processes the [Install] section of the unit file and the symlink may cause corruption. Improvements thanks to @神秘德里克.

5
  • 1
    I'm not sure this actually meets the OPs requirement. The goal is to NOT use systemctl to enable services. In addition, if the machine_name is not known in advance - it's not possible to use this solution. For example - I'm modifying an ISO image that I need to inject a new service configuration in to. I have no idea what the machine_name will be in advance, until the ISO install process is run. The install process unzips an initrd as root filesystem - so the target filesystem is being modified before being compressed in to the initrd.
    – sygibson
    Apr 23, 2020 at 1:28
  • 1
    @sygibson I was the OP and it did for me, at least. The goal was to enable a service without physically booting a machine and manually doing it. Maybe that wasn't clear enough. Also: machine_name can be chosen at random (when running nspawn) as it's just a reference to the spawned machine - after poweroff you can forget about it, AFAIK. It shouldn't change the hostname permanently, again AFAIK. (Even if it does, you'll likely change it during final setup anyways)
    – rudib
    Jun 27, 2020 at 10:05
  • Thanks for posting a clear answer here. This makes sense but feels like a really big hammer. What will happen, for example, if the host machine doesn't run systemd and has no systemd-nspawn nor systemctl? Or isn't even a Linux? (I guess that last one isn't terribly likely but I have ExtFS installed on my Mac... am I SOL trying to prepare such an image if I'm doing it there?) It's really strange that simply making the symlink isn't "enough". Wonder if anyone can explain what the concern for that is.
    – Steven Lu
    Feb 24, 2022 at 4:22
  • Also, it's not clear at all what /install/directory ought to be. All I can imagine here is that when prepping a disk image, this should be the mount point of the rootfs of the target filesystem. Please clarify that.
    – Steven Lu
    Feb 24, 2022 at 4:30
  • For example, the concern might be mitigated by simply removing the [Install] section from the service file entirely.
    – Steven Lu
    Feb 24, 2022 at 5:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .