Layering packages with rpm-ostree from Kickstart

The idea is to be able to run rpm-ostree install <package> from %post section of the Kickstart.

Currently it doesn’t work for me,
if I run following in Anaconda console just after system install (but before reboot), get an error:

[anaconda root@fedora ~]# rpm-ostree status --sysroot=/mnt/sysroot/
Job for rpm-ostreed.service failed because the control process exited with error code.

See "systemctl status rpm-ostreed.service" and "journalctl -xeu rpm-ostreed.service" for details.

× rpm-ostreed.service - rpm-ostree System Management Daemon
     Loaded: loaded (/usr/lib/systemd/system/rpm-ostreed.service; static)
    Drop-In: /usr/lib/systemd/system/service.d
             └─10-timeout-abort.conf
     Active: failed (Result: exit-code) since Wed 2025-03-19 12:07:40 UTC; 127ms ago
 Invocation: 70b346cb36b6427d88c4357422071712
       Docs: man:rpm-ostree(1)
    Process: 5649 ExecStart=rpm-ostree start-daemon (code=exited, status=1/FAILURE)
   Main PID: 5649 (code=exited, status=1/FAILURE)
     Status: "error: Couldn't start daemon: Error setting up sysroot: loading sysroot: fstatat(ostree/deploy): No such file or directory"



   Mem peak: 4M
        CPU: 173ms

Mar 19 12:07:40 fedora systemd[1]: Starting rpm-ostreed.service - rpm-ostre…n...
Mar 19 12:07:40 fedora rpm-ostree[5649]: Reading config file '/etc/rpm-ostr…onf'
Mar 19 12:07:40 fedora rpm-ostree[5649]: error: Couldn't start daemon: Erro…tory
Mar 19 12:07:40 fedora systemd[1]: rpm-ostreed.service: Main process exited…LURE
Mar 19 12:07:40 fedora systemd[1]: rpm-ostreed.service: Failed with result …de'.
Mar 19 12:07:40 fedora systemd[1]: Failed to start rpm-ostreed.service - rp…mon.
Hint: Some lines were ellipsized, use -l to show in full.
error: Loading sysroot: exit status: 1

@siosm

1 Like

Please don’t ping me personally for help on discussion threads. I already watch questions that are tagged Silverblue, etc.

2 Likes

In this case, you can not do that as the system is not booted via (rpm-)ostree so the daemon won’t start. You should layer packages on first boot.

1 Like

Thanks. Please note I’m chasing fully scripted installation, though.
Does Anaconda provides abilities to schedule some commands for the first boot, maybe?

Other possibility that comes to mind is try to create systemd One-time service..

Might be related:

Or what I’m asking for is more naturally solved with Ostree Native Containers by ostreecontainer Kickstart verb?

If you have internet access, you can write a systemd unit that runs on first boot and does the layering.

If you don’t, then you would have to re-create a full ISO using your own composes / commits. This is not super ergonomic to do right now.

1 Like

I have WiFi internet only which I already scripted Network Manager configuration for.
Now only thing left is to approach systemd run my one-time unit after WiFi is set up..

… and we have the facility:

So I ended up with the following.. workaround Kickstart snippet:

%post --erroronfail

mkdir -p /usr/local/lib/systemd/system
cat > /usr/local/lib/systemd/system/rpm-ostree-init.service << 'EOF'
[Unit]
Description=Layering packages

After=network-online.target
Wants=network-online.target

[Service]
ExecStart=rpm-ostree override remove nano nano-default-editor --install=vim-default-editor
ExecStart=rpm-ostree apply-live --allow-replacement
ExecStart=sh -c 'rpm-ostree install --apply-live https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %%fedora).noarch.rpm https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %%fedora).noarch.rpm'
ExecStart=rpm-ostree install --apply-live gnome-tweaks goldendict levien-inconsolata-fonts libavcodec-freeworld libva-intel-driver libva-utils smartmontools systemd-boot-unsigned terminus-fonts translate-shell zsh
ExecStart=rpm-ostree uninstall rpmfusion-free-release rpmfusion-nonfree-release --install rpmfusion-free-release --install rpmfusion-nonfree-release
ExecStart=rpm-ostree apply-live

ExecStop=systemctl disable %N
#ExecStop=rm -v %y

Type=oneshot

[Install]
WantedBy=multi-user.target
EOF

...
%end
1 Like