systemd-nspawn send command with boot flag

894 views Asked by At

In my Debian development machine I set up a systemd-nspawn environment for customizing an embedded systemd.

I'm able to send command to this container from a script, in this way:

systemd-nspawn -q --bind /usr/bin/qemu-arm-static -D $MOUNTPATH /bin/bash << EOF
apt-get update
apt-get -y upgrade
EOF

Now I need to do the same but starting the container with the -b (boot) flag. Is still possible to do that inside a script?

Right now I do the following manually:

  1. start systemd-nspawn with -b flag
  2. login
  3. issue the commands
  4. halt
2

There are 2 answers

0
Robert Smith On

With screen

You'll have to apply a patch to your guest containers agetty, in my case, I had to use gentoo's specifications that enabled me to login as root without a password

Please note that the instructions to enable console-login as root without a password for your automagic adventures varies by distribution. Please check your distributions documentation. More specifically, that on agetty OR inittab if you're using OpenRC.

In my case, I was using /usr/lib/systemd/systemd, so this is how I did it with agetty

# reset the root password
sed -i -e 's/^root:\*/root:/' /mnt/etc/shadow 2>/dev/null

# patch agetty to autologin as root.
mkdir /mnt/etc/systemd/system/console-getty.service.d
cat <<EOF > /mnt/etc/systemd/system/console-getty.service.d/autologin.conf
  [Service]
  ExecStart=
  ExecStart=-/sbin/agetty --noclear --autologin root --keep-baud console 115200,38400,9600 $TERM
EOF

You can then use screen's stuff functionality to write in whatever you'd like to send:

Its a hack, but I couldn't get the "tricky way" working properly. At least not in a systemd-nspawn in which the guest decided to take over the console device. This is not the best solution probably, but it is a working one. Screen can be resource intensive, so I'm most definitely not going to dub this the 'best way', only a 'working way'.

# SCREEN POWERUP
screen -AmdS myguest /bin/bash
screen -S myguest -p 0 -X stuff $'systemd-nspawn -D /mnt --machine my-pc -b 3 --link-journal host'$(echo -ne '\015')
read -t 5

# ------ put whatever you want here: -------
# screen -S myguest -p 0 -X stuff $'yourBashCommandsGoHere'$(echo -ne '\015')

# GUEST AND SCREEN SHOTDOWN
screen -S myguest -p 0 -X stuff $'poweroff'$(echo -ne '\015')
read -t 1
screen -S myguest -p 0 -X stuff $'exit'$(echo -ne '\015')

# Done
echo ":-)"
0
GongT On

systemd-nspawn -D $MOUNTPATH -b arg1 arg2

is just same with

systemd-nspawn -D $MOUNTPATH /bin/init arg1 arg2

/bin/init is a example here, may be any init system (like /usr/lib/systemd/systemd).
it's auto detected.

If you use --boot, then you lose control of the first program in container.

Init system will run your program. But you must follow the instructions of your init system. create init.rc script or systemd service.


and another "tricky way" is:

systemd-nspawn xxxx --boot
sleep 5s
systemd-run -M xxxx /bin/bash << EOF
  apt-get update
  apt-get -y upgrade
EOF