-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding support for performing updates from a container image #128
base: master
Are you sure you want to change the base?
Conversation
any plans for this to be merged? |
Yes, I just have to find the time to finally review it! Sorry for the delay! |
registry.opensuse.org/home/roxenham/slemicro/containers/edge/sle-micro/5.5:20240726 does not exist anymore? |
Hi @joostwestra - yes, that system rebuilds every day and discards already created tags, so you can either select the latest tag, or just build off latest:
|
Any update on timeline for a review of this? |
Since slemicro 6 is also released now, Is it possible to add migration functionality to it through above mechanism, from 5.5 to 6?? Right now to migrate to 6 there is 'transactional-update migrate' command which internally calls zypper migrate, which requires connectivity to SUSEConnect. |
We tested this feature by manually patching it in. We think it is a valuable feature for a wide audience. |
I'll include it in the next major release (hopefully to be released soon), it's just that I'm currently prioritizing finalizing the work on moving the /etc overlays to btrfs subvolumes. |
@laenion Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the implementation! I really love the approach, though I'm not sure how bullet-proof it has to become to merge it. So let me just add a few comments.
It seems that one so far has to specify a specific image, i.e. it won't detect whether there's an update. On the other hand it's also possible to install any image (even other distributions) which will obviously break.
I guess it would make sense to either predefine (e.g. in tukit.conf or transactional-update.conf) the repository and just let the user specify the specific version by default.
In the longer term I think we also want to integrate the functionality into tukit directly as an alternative implementation to snapper. Then the updates could also be triggered by D-Bus and the API.
OCI_RSYNC_EXCLUDES_LIST=() | ||
for i in ${OCI_RSYNC_EXCLUDES}; do | ||
OCI_RSYNC_EXCLUDES_LIST+=("--exclude $i ") | ||
done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the one hand it's good that the directories are excluded explicitly because the directories will be overmounted anyway, on the other hand transactional-update is warning at the end of the update about those files, and the created files would still be available as a reference.
Both ways are valid approaches though, I just wanted to mention this.
|
||
# Merge contents of /etc from container image but preserve existing configuration | ||
log_info "INFO: Merging /etc from container image into existing snapshot, preserving existing configuration..." | ||
tukit ${TUKIT_OPTS} callext ${SNAPSHOT_ID} rsync --ignore-existing ${OCI_RSYNC_ARGS} ${OCI_MOUNT}/etc/ ${SNAPSHOT_DIR}/etc/ |& tee -a ${LOGFILE} 1>&${origstdout} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how this rsync call is different from the one above syncing the root file system. Isn't the result exactly the same when removing /etc from the exclude list?
I guess this rsync call is supposed to synchronize the changed files in /etc from the currently running system into the new snapshot?
if [ "$1" == "--help" ]; then | ||
usage 1 | ||
break | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think a dedicated --help
option for this specific command is useful because it would be the only command with this behavior - I'd include the information about the required parameters in the general help.
@@ -74,6 +75,9 @@ SYSTEM_MANIFEST_FILE="@libdir@/sysimage/tu/system.manifest" | |||
ZYPPER_AUTO_IMPORT_KEYS=0 | |||
ETC_OVERLAY_PATTERN='^[^[:space:]]\+[[:space:]]\+\/etc[[:space:]]\+overlay[[:space:]]\+\([^[:space:]]*,\|\)workdir=\/sysroot\/var\/lib\/overlay\/work-etc[,[:space:]]' | |||
NON_ROOTFS_WHITELIST=("/var/lib/YaST2/cookies" "/var/lib/rpm" "/var/lib/systemd/migrated" "/var/run/zypp.pid") | |||
OCI_RSYNC_ARGS="-a --hard-links --xattrs --acls --inplace" | |||
OCI_RSYNC_EXCLUDES="/etc /var /usr/local /tmp /root /home /srv /opt /sys /dev /proc /run" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of hardcoding this list I'd suggest to dynamically parse it using findmnt
, but also see the comment where the exclude list is processed below.
usage 1 | ||
break | ||
fi | ||
shift |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you wouldn't consume all arguments it would even be possible to install additional packages in one go (e.g. transactional-update apply-oci --image <path> pkg in <package>
.
These calls are perfectly fine. You could use
Indeed, also see my comment in #128 (review).
👍 |
In this PR I'm introducing support for
transactional-update
to be able to consume a container image (or OCI artefact) as the source for the next boot snapshot. This is very important functionality that allows customers to build, distribute, and validate their operating system images via a standardised container image workflow; they can build OS images via Dockerfiles, store and retrieve them via a standard image registry, and put them through standard SBOM and vulnerability checkers.This PR is specifically addressing requirements to enable customers to upgrade an existing machine, regardless of how it was deployed, to a new image-based snapshot, however the initial day1 approach could use tooling such as
kiwi-ng system stackbuild
to build bootable raw and SelfInstall ISO's based on the same container image, which is already a supported feature.The approach taken in this PR:
snapper
(i.e.transactional-update rollback
) functionalityjeos-firstboot
(provided they're in the image!)I could use some help with ensuring that I'm making the correct calls, as I'm mixing
tukit callext
with using the{SNAPSHOT_DIR}
directly. I suspect there's a more elegant/safer/better way of achieving this, hence why it's labelled as a work in progress for now.Further, we likely need to run some validations to make sure that the target image is actually bootable. This code forces a
dracut
andgrub2-mkconfig
run, but I can see this being an area where it may be trivial to make the system difficult to boot and rescue. I'm not an expert here, so I'm wondering whether there are checks that we could execute, and if they fail, we can abort the snapshot. Documentation on how to build an image will be very important, especially as it relates to partitions (or btrfs subvolumes that are ignored) but we should likely do some additional sanity checks to verify the state of the new snapshot rather than blindly closing it and enabling the user to reboot, where we're not able to provide a decent level of confidence in a successful reboot.For testing, I used this on-top of SLE Micro 5.5 and used a test container image available at (
registry.opensuse.org/home/roxenham/slemicro/containers/edge/sle-micro/5.5:20240726
). This is a very simple image that aims to mirror the standard SLE Micro 5.5 packages as defined in the original Kiwi image definition file, i.e. it's not cut down, but has the bare set of packages typically installed, or as defined in the "Default" profile. Of course, it's perfectly possible to modify this image to suit, e.g. adding a package to it is as simple as building and pushing a new image (noting that thesuseconnect
is only required for commercially registered images, this wouldn't be required for Leap Micro or MicroOS:Then, this image can be used as an input to code provided as part of this PR:
Some further guidance from the TU community would be appreciated. Thanks a lot!
[1] This approach aligns well with the
bootc
project (https://containers.github.io/bootc/filesystem.html#etc) to be able to persist/etc
configuration across image updates, which would enable configuration such as OS registration, package repositories, static network configuration, and various other components to persist, and not be overwritten by the OS upgrade. However, one question we may want to answer is whether we want to enable/usr/etc
to enable specific files in/etc
to be overwritten by force by contents found in/usr/etc
to give users a release-valve for changing certain persistent configuration over time as part of a 3-way merge (this PR doesn't do this yet).