3

I install Debian a lot. To do this I have a fully-automated preseed.cfg; at the end of the preseed, it downloads and runs a postinstall.sh script from my TFTP server, which does some additional customization.

I'm in the process of switching from GNOME to LXQTE, and using SDDM instead of GDM. However, SDDM tries to start too quickly for my hardware. To get around this, I've been using systemctl edit sddm to add the following:

[Service]
ExecStartPre=/bin/sleep 5

This works great, and I'd like to automate this process by adding it to the postinstall.sh script. However, I can't figure out how to pass the file contents to systemctl edit via a bash script. How can I do this?

6

You can override the $SYSTEMD_EDITOR environment variable to use a different command other than your editor when running systemctl edit.

For instance, using something like SYSTEMD_EDITOR='cp /path/to/source.file' seems to work OK (even though it's pretty ugly, expecting the last argument to be appended there by systemd!)

For your particular case, you could use:

$ { echo "[Service]"; 
    echo "ExecStartPre=/bin/sleep 5";
  } >~/tmp/sddm-override.conf
$ sudo env SYSTEMD_EDITOR="cp $HOME/tmp/sddm-override.conf" systemctl edit sddm

But all that systemctl edit really does is create an override file (in its case, named override.conf) under the /etc/systemd/system/<service>.service.d/ directory, which is created if it does not exist... So doing that directly is also a totally accepted approach. (See mentions of "drop-in" and "override" in the man page for systemd.unit for more details.)

So, in your case, this would be an appropriate solution:

$ sudo mkdir -p /etc/systemd/system/sddm.service.d/
$ { echo "[Service]"; 
    echo "ExecStartPre=/bin/sleep 5";
  } | sudo tee /etc/systemd/system/sddm.service.d/10-startup-delay.conf
$ sudo systemctl daemon-reload

Which drops a file with the expected contents in the "drop-in" directory for your unit, in which case you can also name it appropriately after what it tries to accomplish.

UPDATED: As @GracefulRestart points out, you need a systemctl daemon-reload after adding a drop-in directly.

  • Thank you for your answer, but I haven't had any luck with it. See my comment to @GracefulRestart; basically the sddm.service.d directory is not created on install, and even manually creating it and the override.conf does not work (even with daemon-reload) - there must be something special about the systemctl edit in particular. – user5104897 Aug 2 '18 at 18:02
  • @user5104897 If you think there's something special with systemctl edit then try the first method I suggested of setting SYSTEMD_EDITOR environment variable to a command that will create the file. I think the issue might actually be with your postinstall script. Are you running that in the root directory at the machine, or is it maybe running from install media and so you're modifying that filesystem and not the one you boot into? Can you give more details on what your postinstall script is and does? Good luck! – filbranden Aug 2 '18 at 20:31
  • 1
    Ah, I was able to get it working with a few changes to the script - I forgot to ~/tmp - we're all good now! – user5104897 Aug 3 '18 at 17:03
4

Since I have not found how to use systemctl edit in a script yet, best practice would be to simulate the systemctl edit sddm command and place the override in the /etc/systemd/system directory, as service units in /usr/lib/systemd/system could be changed when packages are upgraded:

UNIT='sddm.service'
DIR="/etc/systemd/system/${UNIT}.d"
mkdir $DIR
echo -e "[Service]\nExecStartPre=/bin/sleep 5" > ${DIR}/override.conf
systemctl daemon-reload

That should be roughly equivalent to what systemctl edit sddm is doing.

  • I've tried this solution, but I'm running into some problems. After adding this to my postinstall script, sddm still didn't start as expected. I logged in and noticed the /etc/systemd/system/sddm.service.d directory did not exist. After creating this directory and running the echo and daemon-reload myself, I rebooted and it still didn't work. Next I tried adding mkdir /etc/systemd/system/sddm.service.d to the postinstall, and this directory still isn't being created! Regardless, doing it manually doesn't seem to work either. – user5104897 Aug 2 '18 at 17:41
  • When you use systemctl edit sddm, where does systemd put the override.conf? I am not sure why you would not be able to create the directory, check permissions or if selinux is stopping you. – GracefulRestart Aug 2 '18 at 19:57
  • I'm able to create the directory and file manually, but they have no effect even after daemon-reload - it's only when I use systemctl edit sddm that the changes actually take effect. Using systemctl opens a buffer named /etc/systemd/system/sddm.service.d/.#override.conf52ea69f0b57f34f9, but it does ultimately create sddm.service.d/override.conf anyway. – user5104897 Aug 2 '18 at 20:45
0

I want to second the answer given in 3 but I do it this way using tee

env SYSTEMD_EDITOR=tee  sudo -E systemctl edit --system [your_unit_name] < [your_content_file]

When doing it this way you can feed the content via stdin rather than from a file, which can be useful when invoking systemctl from a script.

  • If you move SYSTEMD_EDITOR=tee after sudo you can remove env and -E. – Robin A. Meade Feb 14 at 23:39
-2

I'd attack the file directly:

sed -i 's/\[Service]/ a\
ExecStartPre=/bin/sleep 5' /usr/lib/systemd/system/sddm.service
  • 1
    editing files managed by a package is generally unreliable. An override would probably be a better option. – smokes2345 Aug 1 '18 at 22:36
  • This is incorrect. You shouldn't edit units from /usr/lib directly, since the modifications are probably going to get clobbered next time the package is upgraded. Furthermore, what you suggest is likely to cause syntax errors, since the unit probably already has a [Service] section and shouldn't really get another. Drop-ins are the correct way to deal with this kind of overrides. See the other answers for more details. – filbranden Aug 1 '18 at 22:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.