Unexpected state: /run/ostree-booted found, but no /boot/loader directory

Unexpected state: /run/ostree-booted found, but no /boot/loader directory

Hi all,

I realise this isnt ublue related but I know this community does a lot with bootc so I am hoping someone can point out the issue.

I am creating a derived bootc image using RHEL10 in my homelab. The container itself builds without error and the QCOW2 created using bootc-image-builder also completes without error however the /boot/loader directory is empty. I identified the issue when running sudo bootc status’ at which point I get the error Unexpected state: /run/ostree-booted found, but no /boot/loader directory.

The only difference I see from my deployment and online examples is that I am running bootc-image-builder on Fedora Silverblue. I have installed the osbuild-selinux the bootc-image-builder prerequisites .

The containerfile looks as follows;

FROM  registry.example.com.au/rhel10/rhel-bootc:latest

ARG TIMEZONE='Australia/Sydney'
# policycoreutils-python-utils is required to SELinux labelling
ARG INSTALL_PACKAGES='restic tmux policycoreutils-python-utils cloud-init firewalld tuned bash-completion just'
ARG REMOVE_PACKAGES='subscription-manager'

COPY ./bin/install /usr/local/bin/
COPY ./system-files/ /tmp/system-files/

RUN <<EOF
	set -xeuo pipefail
	
	#################################################
	# Configure Local Yum Repositories
	#################################################
	install -D --group=root --owner=root --mode=0644 /tmp/system-files/yum.repos.d/*.repo --target-directory=/etc/yum.repos.d/
	dnf remove --assumeyes ${REMOVE_PACKAGES}
	dnf install --assumeyes ${INSTALL_PACKAGES}
	

	#################################################
	# Configure Private Registry and Pull Secret
	#################################################
	install -D --group=root --owner=root --mode=0644 /tmp/system-files/podman/registry.example.com.au.conf /etc/containers/registries.conf.d/
	# Note: The pull secret is a pre-autheticated token for reguser to registry.example.com.au
	install -D --group=root --owner=root --mode=0600 /tmp/system-files/podman/auth.json /usr/lib/ostree/

	#################################################
	# Configure Transient / and /etc Partitions
	#################################################
	sed -Ezi '/(\n|^)\[root\]\ntransient = true/!s/$/[root]\ntransient = true\n/' /usr/lib/ostree/prepare-root.conf
	sed -Ezi '/(\n|^)\[etc\]\ntransient = true/!s/$/[etc]\ntransient = true\n/' /usr/lib/ostree/prepare-root.conf
	# Configure the initramfs to apply transient / and /etc
	set -x; kver=$(cd /usr/lib/modules && echo *); dracut -vf /usr/lib/modules/$kver/initramfs.img $kver

	#################################################
	# BootC Workarounds and Fixes
	#################################################
	# rpm-ostree-fix-shadow is a unit created in response to a bug in rpm-ostree where the /etc/shadow, /etc/shadow-,
	# /etc/gshadow and /etc/gshadow files in have the world-readable bit set as per CVE-2024-2905. Reviewing the
	# files idenitifed that the default state is to have permissions zeroed out which is correct. The unit was 
	# failing at boot time. The presence of the follow file is a condition that prevents the service running, i.e;
	# ConditionPathExists=!/etc/.rpm-ostree-shadow-mode-fixed2.stamp
	install -D --group=root --owner=root --mode=0644 /dev/null /etc/.rpm-ostree-shadow-mode-fixed2.stamp

	# Service published bootc facts to Red Hat Subscription Manager, we are not using Red Hat Subscription Manager
	# and therefore  disabling the service
	systemctl disable bootc-publish-rhsm-facts.service

	#########################################
	# Post Build Clean Up Tasks
	########################################
	# Remove uneeded build binaries
	rm -rf /tmp/system-files /usr/local/bin/install
	# Clean dnf cache
	dnf clean all
	# Remove caches and build logs
	rm -rf /var/{cache,log} /var/lib/{dnf,rhsm}
	# Commit ostree changes
	ostree container commit
	# Run a linter over the container file
	bootc container lint	
EOF

I have tried with both transient root and etc and without (so I am not rebuilding initramfs.

I am not using a config.toml file, or cloud-init to modify the partition layout.

Has anyone come across this issue?

Thanks,

Adam

The workaround I have identified is to mount boot again

sudo mount /dev/disk/by-label/boot /boot

This then resolves the issue but my concern is this may be symptomatic of another larger issue.

A simpler containerfile to replicate the problem is;

This occurs with RHEL, CentOS and Fedora bootc images.

FROM quay.io/centos-bootc/centos-bootc:stream9

RUN useradd adamRUN echo “adam:password” | chpasswd

RUN echo -e ‘[etc]\ntransient=true’ >> /usr/lib/ostree/prepare-root.conf && set -x; kver=$(cd /usr/lib/modules && echo *); dracut -vf /usr/lib/modules/$kver/initramfs.img $kver

The qcow is being generated as follows. I have tried this on my Fedora Silverblue 43 system and a RHEL 10 virtual machine

 podman run \
    --rm \
    -it \
    --privileged \
    --pull=newer \
    --security-opt label=type:unconfined_t \
    -v ./output:/output \
    -v /var/lib/containers/storage:/var/lib/containers/storage \
    quay.io/centos-bootc/bootc-image-builder:latest \
    --type qcow2 \
    --use-librepo=True \
  https://my-private-repo/bootc-test

I am hoping I am just making a silly mistake otherwise I assume everyone playing with bootc would be experiencing this.