1

I'm using the systemd.run kernel parameter to apply some auto-configuration tasks on the first boot of Manjaro ARM minimal like setting the hostname, adding a default user, ... and I'd like to install packages using pacman. Everything works except installing pacman packages. For example, I'm trying to update all packages and install vim:

pacman -Syu --noconfirm
pacman -S --noconfirm vim

This throws several errors for each mirror, for example

+ pacman -Syu --noconfirm
:: Synchronizing package databases...
 core downloading...
 extra downloading...
 community downloading...
error: failed retrieving file 'core.db' from manjaro.mirrors.lavatech.top : Could not resolve host: manjaro.mirrors.lavatech.top
warning: too many errors from manjaro.mirrors.lavatech.top, skipping for the remainder of this transaction
error: failed retrieving file 'extra.db' from manjaro.mirrors.lavatech.top : Could not resolve host: manjaro.mirrors.lavatech.top
error: failed retrieving file 'community.db' from manjaro.mirrors.lavatech.top : Could not resolve host: manjaro.mirrors.lavatech.top
error: failed retrieving file 'core.db' from ftp.nluug.nl : Could not resolve host: ftp.nluug.nl

I tried to ping my local server as well as a internet domain, e.g.

+ ping -c1 192.168.0.19
ping: connect: Network is unreachable

So it seems that the network connection is not established yet when the script runs. I tried systemd.wants but it still doesn't work, the network is not avaliable. Also tried different units as systemd.wants in cmdline.txt:

systemd.wants=systemd-networkd.service
systemd.wants=systemd-networkd-wait-online.service
systemd.wants=network-online.target
systemd.wants=dhcpcd.service

The systemd directives in /boot/cmdline.txt:

systemd.run=/boot/my_init_wrapper.sh systemd.run_success_action=reboot systemd.unit=kernel-command-line.target systemd.wants=systemd-networkd.service

Since the systemd-run-generator only mention three options (run, run_success_action and run_failture_action) I think that I misunderstood the first doc and it seems not possible to set dependencies for systemd.run.generator. I'm wondering about this, since systemd units itself can specify different types of dependencies. Is there any other way how we can speficy them in the kernels cmdline.txt?

I'm trying this on a Raspberry Pi 4. But since this question is only about systemd, imho it doesn't matter if it runs on a pi or any other machine with systemd. So I posted it here as general linux question instead of the RPI platform.

1 Answer 1

1

I think in this case you are better off to not go via systemd.run but to make it a normal service and make use of ConditionFirstBoot=yes - at least for the pacman part.

According to the manual, such units better also refer to first-boot-complete.target

[Unit]
Description="Update packages & install vim"
ConditionFirstBoot=yes
Wants=first-boot-complete.target
Before=first-boot-complete.target
Wants=network-online.target
After=network-online.target

[Service]
#optional ping test
#ExecCondition=/usr/bin/ping -c 2 -w 2 manjaro.org
#not running arch - adapt pacman path if need be:
ExecStart=/usr/bin/pacman -Syu --noconfirm
ExecStart=/usr/bin/pacman -S --noconfirm vim

[Install]
WantedBy=default.target

The ping test might be interesting due to the uncertainty of what "network is online" means.


Citation from the manual for the first boot condition:

ConditionFirstBoot=

Takes a boolean argument. This condition may be used to conditionalize units on whether the system is booting up for the first time. This roughly means that /etc/ is unpopulated (for details, see "First Boot Semantics" in machine-id(5)). This may be used to populate /etc/ on the first boot after factory reset, or when a new system instance boots up for the first time.

For robustness, units with ConditionFirstBoot=yes should order themselves before first-boot-complete.target and pull in this passive target with Wants=. This ensures that in a case of an aborted first boot, these units will be re-run during the next system startup.

If the systemd.condition-first-boot= option is specified on the kernel command line (taking a boolean), it will override the result of this condition check, taking precedence over /etc/machine-id existence checks.

4
  • Sounds interesting, but how do I create the unit? Is it possible to use systemd.run to create this unit? Is it then started after systemd.run or do I need an additional reboot?
    – Lion
    Jan 17, 2022 at 7:16
  • @Lion I wouldn't see why not but cannot test it. An additional reboot would be contradicting regarding the first-boot requirement.
    – FelixJN
    Jan 18, 2022 at 9:53
  • That's the issue I see but it's already struggeling with the network part. I tried network-online.target, nss-lookup.target and network.target network-online.target but still getting the same Could not resolve host errors from pacman. When running the command like /usr/bin/pacman -S --noconfirm vim manually in a terminal, the package got successfully installed without any error.
    – Lion
    Jan 18, 2022 at 21:19
  • 1
    After trying many things, also scripts who are waiting for an IP with hostnamectl -I, it seems that we don't have any network in scripts started by systemd.run. The only way I could work around this is specifying Restart=on-failure and RestartSec=5. Instead of ConditionFirstBoot=yes I use ConditionPathExists=!/boot/my_init_done, so it's started after the first boot (where systemd.run is started). The file /boot/my_init_done got removed after my packages were installed. Creates some errors until the DNS works, but I couldn't find a better solution.
    – Lion
    Jan 19, 2022 at 0:33

You must log in to answer this question.

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