Update composefs, unified storage#2044
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors how container image manifest and configuration are handled for composefs deployments. Instead of storing them in a separate .imginfo file, the manifest digest is now stored in the .origin file, and the manifest/config are read directly from the composefs repository. This is a good improvement that centralizes image metadata storage. The changes are consistent across the codebase, and backward compatibility for older deployments with .imginfo files is maintained. I've found one area for improvement regarding repository handling efficiency.
ef5cb0f to
d1f366d
Compare
|
OK, this is passing tests now and I think is a notable cleanup. I think this may be one of the last ~breaking changes for the composefs installation layout. |
|
Actually thinking about this more...it feels like we should really be creating tags in the cfs repo instead of using this additional root stuff. That's effectively what ostree does with Basically we create
In particular a key thing is that this works if the composefs repo holds other data such as app images. |
215b824 to
e3b7826
Compare
| }; | ||
|
|
||
| let origin_filename = format!("{deployment_id}.origin"); | ||
| let Some(origin_contents) = state_dir.read_to_string_optional(&origin_filename)? else { |
There was a problem hiding this comment.
The .origin file should always exist right?
Cargo.toml
Outdated
| needless_borrow = "allow" | ||
| needless_borrows_for_generic_args = "allow" | ||
|
|
||
| [patch."https://github.com/composefs/composefs-rs"] |
There was a problem hiding this comment.
I don't think we need this
There was a problem hiding this comment.
We do it's for composefs/composefs-rs#263
|
|
||
| tracing::debug!("img_bootloader_diff: {img_bootloader_diff:#?}"); | ||
| // Bootloader entries without a state dir are from interrupted cleanups. | ||
| let orphaned_boot_entries: Vec<_> = bootloader_entries |
There was a problem hiding this comment.
this will always be an empty vec iiuc? Since we always delete the bootloader entries first
The open_config() return type changed from a tuple to the OpenConfig struct. Point the bootc reverse-dep CI at bootc-dev/bootc#2044 which has the matching API update, until that PR is merged to main. Assisted-by: OpenCode (Claude Opus 4) Signed-off-by: Colin Walters <walters@verbum.org>
The OCI digest cleanup breaks the bootc API boundary. Re-enable once bootc-dev/bootc#2044 lands on bootc main. Assisted-by: OpenCode (Claude Opus 4) Signed-off-by: Colin Walters <walters@verbum.org>
1af0080 to
e19a663
Compare
e19a663 to
d5ba655
Compare
d5ba655 to
c936426
Compare
| let id = composefs_oci::generate_boot_image(&repo, &pull_result.manifest_digest) | ||
| .context("Generating bootable EROFS image")?; | ||
|
|
||
| // Get boot entries from the OCI filesystem (untransformed). |
There was a problem hiding this comment.
comment seems out of place here. Maybe it was intended for the next line? Also, I don't think we "transform" the boot entries in any way
| .context("Init cfs repo")?; | ||
| // We don't need to hard require verity on the *host* system, we're just computing a checksum here | ||
| repo.set_insecure(true); | ||
| repo.set_insecure(); |
There was a problem hiding this comment.
a bit confusing as I'd assume passing enable_verity = false in the init_path should've set this automatically
| /// The `spec::ImageReference` stores transport as a string (e.g. "registry:", | ||
| /// "containers-storage:"). This parses that into a proper typed reference | ||
| /// that renders correctly for skopeo (e.g. "docker://quay.io/some-image"). | ||
| pub(crate) fn get_imgref(transport: &str, image: &str) -> Result<containers_image_proxy::ImageReference> { |
There was a problem hiding this comment.
we should be able to use containers_image_proxy::Transport
`just bcvk up` with `BOOTC_variant=composefs` silently ignored the variant — it read the env var but never passed `--composefs-backend` or related flags to `bcvk libvirt run`, so the VM always installed with the ostree backend. Extract a shared `BcvkInstallOpts` helper (new `bcvk.rs` module) that both `sysext.rs` and `tmt.rs` use to build bcvk CLI arguments from `BOOTC_*` environment variables. This fixes the sysext path and eliminates the duplicated firmware/install arg construction in tmt. Assisted-by: OpenCode (Claude Opus 4) Signed-off-by: Colin Walters <walters@verbum.org>
c936426 to
64626d3
Compare
|
This now requires composefs/composefs-rs#218 |
64626d3 to
f5a3be9
Compare
The xtask run-tmt command now reads BOOTC_bootloader, BOOTC_filesystem, BOOTC_seal_state, and BOOTC_boot_type directly via clap env support. When BOOTC_variant=composefs, --composefs-backend is implied automatically. This means `just test-tmt` works correctly with composefs env vars set, without the Justfile needing to forward flags manually. Assisted-by: OpenCode (Claude Opus 4) Signed-off-by: Colin Walters <walters@verbum.org>
Add a podman_client module for pulling container images through podman's native libpod HTTP API with streaming per-blob download progress displayed via indicatif. Starts a transient `podman system service` against bootc's custom storage root (reusing bind_storage_roots and setup_auth helpers) and talks to it over a Unix socket. The response NDJSON stream is read line-by-line via AsyncBufReadExt. Also fix get_ensure_imgstore() to work on composefs-only systems by falling back to physical_root when ostree is not initialized. Factor setup_auth() out of new_podman_cmd_in() so both the CLI podman commands and the API service share the same auth setup. Assisted-by: OpenCode (Claude Opus 4) Signed-off-by: Colin Walters <walters@verbum.org>
The composefs backend has a multi-dimensional configuration space (variant, bootloader, boot_type, seal_state, filesystem) with non-obvious constraints between them. Add a clear reference table and common workflow examples to CONTRIBUTING.md, and a quick-start cheat sheet to the Justfile header. Assisted-by: OpenCode (Claude Opus 4) Signed-off-by: Colin Walters <walters@verbum.org>
By far the biggest change here is to how we do our GC logic. Now, composefs-rs itself holds refs to the EROFS images; we just need to hold onto the images themselves. Assisted-by: OpenCode (Claude Opus 4) Signed-off-by: Colin Walters <walters@verbum.org>
For registry transports, pull_composefs_repo() now goes through bootc-owned containers-storage first (via podman pull), then imports from there into the composefs repo via cstor (zero-copy reflink/hardlink). This means the source image remains in containers-storage after upgrade, enabling 'podman run <booted-image>'. Non-registry transports (oci:, containers-storage:, docker-daemon:) continue using the direct skopeo path. Also fix composefs_oci::pull() callsite to pass the new zerocopy parameter added in the composefs-rs import-cstor-rs-rebase branch. Clean up GC to use CStorage::create() directly instead of going through storage.get_ensure_imgstore() which requires ostree and fails on composefs-only systems. Remove the unreferenced fsck module. Assisted-by: OpenCode (Claude Opus 4) Signed-off-by: Colin Walters <walters@verbum.org>
Instead of reading the in memory filesystem to get /usr/lib/os-release get it from the mounted EROFS. This is also prep for providing backwards compatibility due to our newly introduced prefix `bootc_composefs-` where we'll need to create new boot entries and we can get the `os_id` from the mounted root Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com> Signed-off-by: Colin Walters <walters@verbum.org>
f5a3be9 to
921a08e
Compare
While finishing up GC, we had come up with the idea of prepending our boot binaries (UKI PEs, BLS directories) with a certain prefix and we ended up hard requiring these prefixes. If someone has an older version of bootc which they used to install their system with, then upgrade to a new version, many if not all of the important operations would cease to work. This basically handles the backwards compatibility of new binaries on older systems by prepending our custom prefix to all existing boot binaries Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com> Signed-off-by: Colin Walters <walters@verbum.org>
Check if the repo has meta.json file and if not apply our fix of prepending custom prefix to our bootloader entries and boot binaries Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com> Signed-off-by: Colin Walters <walters@verbum.org>
Add some basic infra to mock up enough of an installed root to use in unit tests - specifically targeted for the bootloader logic. Assisted-by: OpenCode (Claude Opus 4) Signed-off-by: Colin Walters <walters@verbum.org>
921a08e to
eeaeca3
Compare
The latest composefs-rs stores manifest and config objects and
the manifest becomes a GC root, so we can use that instead of
.imginfosidecar files.
The flow now is:
bootloader entry -> deployment -> origin file
-> manifest digest -> manifest -> [config | objects]
For backward compatibility, fall back to the legacy .imginfo
file if the .origin does not contain a manifest_digest key.
Drop the really old hacky fallback that did network fetches.
Note the manifest becomes part of the GC root.