Skip to content

install: Add --preserve-var and --merge-etc to to-existing-root - #2384

Draft
ckyrouac wants to merge 2 commits into
bootc-dev:mainfrom
ckyrouac:image-to-package
Draft

install: Add --preserve-var and --merge-etc to to-existing-root#2384
ckyrouac wants to merge 2 commits into
bootc-dev:mainfrom
ckyrouac:image-to-package

Conversation

@ckyrouac

Copy link
Copy Markdown
Collaborator

This is AI generated with lots of guidance.


Add two flags to bootc install to-existing-root that are most useful
when migrating a package-mode system to a bootc image built externally:

--preserve-var Copy the running system's /var data into the new
deployment, and write a package-mode GRUB rollback
boot entry.

--merge-etc Apply the running system's /etc customisations onto
the new deployment via a 3-way merge.

Typical usage:

podman run --rm --privileged --pid=host --user=root:root
-v /dev:/dev --security-opt label=type:unconfined_t
-v /:/target -v /var/lib/containers:/var/lib/containers

bootc install to-existing-root
--preserve-var
--merge-etc
--acknowledge-destructive

Two robustness fixes surfaced while exercising the 3-way merge against
real package-mode `/etc` trees (see the upcoming `--merge-etc` install
flag):

- In merge_leaf(), when copying a modified file into the new /etc,
  skip (with a warning) rather than fail when the cap-std copy hits
  "a path led outside of the filesystem". This happens when a path
  component in the current /etc leads through an absolute symlink
  that escapes the cap-std root (e.g. /etc/alternatives symlinks);
  the image's existing content wins for that path instead of
  aborting the whole merge. Clarify the comment on the analogous
  lstat-based removed-path check for consistency.

- Warn and skip, instead of bailing, when a modified host file/symlink
  newly defaults to a directory in the target image (e.g.
  /etc/ssl/certs is a symlink in Fedora package mode but a directory in
  the bootc base image).  The image's directory wins and the host's
  customization is dropped for that path.

Update the file-to-directory unit test to match the new behavior.

Assisted-by: AI
Add two flags to `bootc install to-existing-root` that are most useful
when migrating a package-mode system to a bootc image built externally:

  --preserve-var   Copy the running system's /var data into the new
                    deployment, and write a package-mode GRUB rollback
                    boot entry.

  --merge-etc      Apply the running system's /etc customisations onto
                    the new deployment via a 3-way merge.

Typical usage:

  podman run --rm --privileged --pid=host --user=root:root \
      -v /dev:/dev --security-opt label=type:unconfined_t \
      -v /:/target -v /var/lib/containers:/var/lib/containers \
      <fleet-image> \
      bootc install to-existing-root \
          --preserve-var \
          --merge-etc \
          --acknowledge-destructive

The implementation lives in the new `install/migrate` module; see its
module-level docs for the on-disk layout and the /var and /etc
migration strategies (reflink copy vs. plain copy, the pkgmode-rollback
BLS entry, and the etc-merge 3-way merge). install_to_existing_root()
extracts the two flags before opts is consumed, stashes the running
kernel/initramfs ahead of install_to_filesystem() when --preserve-var
is set (since that wipes /boot), and runs the post-install migration
steps afterward.

migrate.rs includes unit tests covering the pkgmode-rollback path
layout and the new /var path derivation from the deployment dir.

Assisted-by: AI
@bootc-bot
bootc-bot Bot requested a review from cgwalters August 17, 2026 16:06
@github-actions github-actions Bot added the area/install Issues related to `bootc install` label Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/install Issues related to `bootc install`

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant