Rolling back bootc systems
In this lab, you’ll look at rollbacks and examine how bootc handles directories on updates.
Rolling back changes to the virtual machine
You should still be logged into the bootc VM (the prompt should look like ` [core@localhost ~]$`), if not log back in now.
|
We have a new built-in option available to image mode systems that typically takes more preparation with package mode operations: the rollback.
Since bootc
manages state on disk, we have the previous working system available to us. Normally, we’d need to have set up snapshots or refer to a backup but bootc
automatically provides us the rollback built in.
Let’s check for an available rollback option to get us back to the previous image.
sudo bootc status
No staged image present Current booted image: node.cxdrb.cxdrb.gcp.redhatworkshops.io/httpd Image version: 9.20250326.0 (2025-04-04 14:28:06.536999208 UTC) Image digest: sha256:737be173b45120c062473e9a88d020bc33c32a9069d4c257b74e4f5ab7241e41 Current rollback image: node.cxdrb.cxdrb.gcp.redhatworkshops.io/httpd (1) Image version: 9.20250326.0 (2025-04-04 14:11:45.808515934 UTC) Image digest: sha256:1e69b8a519eccf248e235960dd5eef3c5c546226c0000c655126e00e11438519
1 | the on-disk deployment before our most recent update. |
Looking at the status output, we can see the section marked rollback
now has image information. There are at most 3 images available at any one time: staged for next deployment, the current booted deployment, and a rollback of the last active deployment. If for some reason you needed to go back further, you can deploy directly from the registry instead.
Rollbacks are as simple as running one command. Let’s get this image back to the previous state then we can dig into what happened.
sudo bootc rollback
bootfs is sufficient for calculated new size: 0 bytes Next boot: rollback deployment
You will also find the value of rollbackQueued
in the full YAML output has been updated as well. This can be useful to check before restarting a system. By adding the --format
flag to the bootc status
command we can get more details about the various images and operating state.
sudo bootc status --format yaml | grep Queued
rollbackQueued: true
You can also check the boot order in the spec
block to see what has been sent to the bootloader.
sudo bootc status --format yaml | grep Order
bootOrder: rollback
Feel free to explore the full output of bootc status --format yaml
on your own.
After the reboot, the rollback
image will become the booted image, and will also become the new default in the boot order. Before doing so, please make sure you are logged in to the virtual machine and not the hypervisor, the prompt should look like [core@localhost ~]$
.
sudo systemctl reboot
How image mode handles directories
On the lab host, we’re going to make some changes to the Containerfile to account for how
directories are managed by bootc
.
In an image mode system, bootc
manages available images on disk for updates and rollbacks.
You just created an update, applied it, then returned to a previous version all through bootc
.
Behind the scenes, bootc
handles the following directories differently, which is what allows
for the seamless update and rollback experience.
-
/usr
→ image state, contents of the image will be extracted and overwrite local files -
/etc
→ local configuration state, contents of the image are merged with a preference for local files -
/var
→ local state, contents of the image will be ignored after the initial installation of any image
The configuration files we added to /etc
showed up after the update as a result of the merge treatment of bootc. If we’d made local changes that conflicted, we’d see the local changes rather than the new configs.
Our initial web page went in /var
which means after it was unpacked from the original image, bootc
treated it as local machine state. So the change in the Containerfile wasn’t applied to the running host.
Since we want to control everything about our webserver from the image, we’ll need to make some changes
to where we put content and how we serve it in Apache.
FROM registry.redhat.io/rhel9/rhel-bootc:9.5
RUN dnf install -y httpd
ADD etc/ /etc
RUN <<EOF (1)
set -euxo pipefail
mv /var/www /usr/share/www
sed -i 's-/var/www-/usr/share/www-' /etc/httpd/conf/httpd.conf
EOF
RUN echo "Hello Red Hat Summit 2025!!" > /usr/share/www/html/index.html
RUN systemctl enable httpd.service
1 | Runs several commands using the heredoc format instead of using the & operator to join multiple commands |
Let’s break down that new RUN
directive.
The httpd
package drops content in /var/www
by default, and on bootc systems
/var
is machine local. For this example, to manage web content via the image,
we need to move it to somewhere under bootc
control. We move
the default package contents to a new location in /usr
then update the Apache
configuration to serve pages from this new directory.
Since the heredoc support for containerfiles essentially reads it as a mini-bash script, using set -euxo pipefail
will show what’s run and cause any errors in these commands to bubble up and stop the build. This way we don’t need to wait to catch an error on the host to start troubleshooting.
We’ve also changed the echo line to create the index.html in the new docroot location.
Rebuild the image with our new configuration and index page. Since this is a rebuild, podman will reuse the existing layers if there are no changes. This makes updates faster and take less space. Notice the push to the registry also only pushes those layers that contain changes.
podman build --file Containerfile --tag {registry_hostname}/httpd
And make sure to push it to the registry:
podman push {registry_hostname}/httpd
Updating the virtual machine
Now you can ssh into the virtual machine
ssh core@qcow-vm
Previously, we checked for an update, downloaded and staged it locally to be activated, then manually rebooted
the system to have the update take effect. This is a very good procedure for a manual update or in places
where we need to schedule any outages ahead of time, say during a maintenance window. We can do this all at
once by adding a flag to the update
command. This gives us a way to automate the process, like with a systemd
timer. Image mode hosts ship with this timer by default.
systemctl list-timers bootc-fetch-apply-updates.timer
NEXT LEFT LAST PASSED UNIT ACTIVATES Wed 2024-07-24 16:13:… 1h 44min left - - bootc-fetch-apply-upd… bootc-fetch-apply-upd… 1 timers listed. Pass --all to see loaded but inactive timers, too.
Instead of waiting for this timer to trigger, we can immediately apply the new update and reboot.
Since we rolled back to an image that did not include our drop-in file for sudo
, we will be prompted for our password. The drop-in file doesn’t have any local changes, so updates (and presence) are based on the image deployed, like our new web page. This is another thing to keep top of mind when moving between images, especially during a rollback.
sudo bootc update --apply
layers already present: 69; layers needed: 3 (6.2 kB) Fetched layers: 6.10 KiB in 17 seconds (373 B/s) Deploying: done (4 seconds) Queued for next boot: node.cxdrb.cxdrb.gcp.redhatworkshops.io/httpd Version: 9.20250326.0 Digest: sha256:fe4feb4238bf1601df67b7feb04a9f1cf6fab208431af6ebd564fad5a3b7a637 Total new layers: 72 Size: 1.2 GB Removed layers: 3 Size: 185.1 MB Added layers: 5 Size: 185.1 MB Rebooting system Shared connection to qcow-vm closed.
Remember that the update will detail what layers are new, removed, or added, but this time will immediately reboot.