Repository navigation
[RFC] feature: Carry sysext and confext images in COSI files - #789
Paco Huelsz (frhuelsz) wants to merge 15 commits into
Conversation
Proposes an optional `extensions` section in COSI metadata (revision 1.3) holding `sysexts` and `confexts` arrays. Each entry reuses the existing `ImageFile` object to reference a ZSTD-compressed DDI under `images/extensions/`, plus an optional destination path mirroring the Host Configuration `Extension` object. Covers the metadata schema, tar layout, versioning and forward-compatibility, Trident-side consumption (effective extension set across the extensions, osconfig and selinux subsystems), A/B update and rollback semantics, the Host Configuration interaction, and validation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: 1 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
An extension-only change to a COSI changes the metadata hash, which forces an A/B update via ab_update_required() before any subsystem is consulted. Adds an OS content digest recorded in Host Status, and a requested-then-verified Runtime Update path gated on digest equality, with refusal as the only failure mode. Rejects an extension-only COSI variant and records the weaker rollback guarantee of the runtime path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Added a section on extension-only updates, and revised the scope accordingly. The gap was real. An extension-only COSI is the wrong shape. The metadata root requires Mechanism. An OS content digest over the parts of the metadata that determine the deployed OS ( The path is requested and then verified, never inferred. It proceeds only when a Runtime Update is explicitly requested, the digests match, and the recorded image is the deployed one. Otherwise Trident refuses with a structured error naming what differs. It must not promote the operation to an A/B update, and must not apply the extension change while leaving other changes unapplied. Refusal is the only acceptable failure, which is what keeps a partially-applied state unreachable. Rollback is weaker on this path, and that is why it is not automatic. Three questions added to the open list:
|
…ruction Replaces the OS content digest with a structured summary of the deployed image's metadata, recorded in the Host Status, so Trident can distinguish a partition change from an extension-only change from a no-op, and report which partition differs. Falls back to the current os.image.sha384 comparison where no summary is recorded. Adds the construction requirement: filesystem images are not reproducible, so an extension-only COSI must be built by copying an existing COSI's region images verbatim rather than by rebuilding. An unreproducible build degrades to a redundant A/B update, never a skipped one. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Revised, on both points. Storing the metadata. Replaced the single digest with a structured summary of the deployed image's metadata, recorded in the Host Status: for each entry in Excluded, with reasons: A record rather than a digest, since the digest is derivable from it and the record additionally lets Trident report which partition differs. Not the full metadata, since This gives the three outcomes, including the no-op case, which the previous revision missed:
The summary carries its own schema version. Where it is absent or of an unrecognised version, Trident falls back to comparing Construction, and the reproducibility problem. This is the more important of the two, and it invalidates the obvious approach. Filesystem UUIDs, inode timestamps, superblock creation and mount times and allocation order all vary between builds, and ZSTD output varies with compression level and library version. Rebuilding from the same source will not generally produce the same images. So requiring reproducible rebuilds is the wrong approach. The build operation is not "rebuild the image identically with a different extension set", it is "copy an existing COSI, replacing its extension set". Region images and their metadata entries are copied verbatim from the input COSI; no filesystem is rebuilt and no region image is recompressed. Only the extension tar members, the Equality is then guaranteed by construction rather than hoped for through reproducibility, and the operation is a tar rewrite rather than an image build. This reframes the writer requirement from a reproducible-builds effort into a bounded COSI-to-COSI rewrite, and it is now listed under Dependencies. Where a COSI is rebuilt from source instead, its region images differ, the summary differs, and Trident selects an A/B update. That is the safe outcome: the mechanism degrades to current behaviour rather than misclassifying a changed OS as unchanged. The failure mode of an unreproducible build is a redundant A/B update, never a skipped one. Open questions updated accordingly: the exact coverage of the summary ( |
- Add a deployed extension inventory in Host Status; the Host Configuration cannot represent bundled extensions, so spec_old does not describe what is deployed. - Give effective entries a source discriminator; update_host_configuration errors when a processed extension has no matching Host Configuration entry, and compressed and raw sha384 values must never be compared against one another. - Record three prerequisite defects: in-place replacement deletes the newly installed image when ID and destination are unchanged; runtime finalize and rollback build their context with image: None so staged payloads must be durable; extension placement is validated against the Host Configuration only and before the COSI is read. - Correct the A/B rollback claim, which held only for Host Configuration entries, and drop the unsupported read-only assertion. - SELinux check must move to a hook running on every servicing type; it sits in configure(), which returns early for runtime updates. - Split metadata-time from payload-time validation; omitted paths cannot be collision-checked statically, and there is no load-time member existence check since tar entries are discovered lazily. - Warn on extension-release ID mismatch only; systemd accepts a VERSION_ID mismatch when SYSEXT_LEVEL matches. - Note that an omission by an older reader does not self-heal, and that a no-op must still persist the accepted image. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Inventory and image summary need current/pending records, mirroring spec/spec_old, or finalize cannot reconstruct the target set and rollback cannot reconstruct the previous one. - Scope the summary comparison to the image's servicing requirement; select_servicing_type still takes the maximum across subsystems, so an extension-only runtime update also requires no other subsystem to need A/B. - Disk streaming places extensions but osconfig returns early on is_stream_image, so the merge units are never enabled. - Replace the blanket verity rejection: the root-verity /etc overlay is backed by var/lib/trident-overlay on an A/B volume, so /etc/extensions is a supported destination on clean install and A/B update. - Stage on the destination filesystem; the fixed /var/lib/extensions/.staging assumes /var is writable and makes cross-filesystem placement non-atomic. - The permitted-directory allow-list is Trident policy, not a format property; keep it out of the schema and cover it in Rust validation tests. - Move the servicing-type request surface out of Open Questions, where it contradicted its listing as a prerequisite. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Include fsType in the deployed image summary; it drives resize decisions, so two images differing only in fsType must not compare equal. - Promotion of pending records follows the servicing type: rebooting servicing reaches *Finalized before reboot and commits only after booting the expected root, so the pending record must survive the reboot and be discarded when the boot check fails. - ManualRollbackChainItem carries only kind, spec, active volume and install index, so it must be extended or manual rollback cannot restore the bundled extension set. - Remove the stale Future Possibility that restated the now-required inventory. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- A manual runtime rollback has neither the target COSI nor the superseded payload, so inventory metadata alone cannot restore a bundled extension. Either retain payloads for the depth of the rollback chain, or refuse the operation; restoring nothing silently is not acceptable. - ManualRollbackRuntime promotes its pending record on completion. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The runtime path was a stated requirement but absent from the exit criteria and marked deferrable in the plan. Add it to the exit criteria and state that step 5 may land separately but is required for the RFC to be complete. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Streaming places extension files but osconfig returns early on is_stream_image, so the merge units are never enabled. Refuse to stream a COSI carrying extensions rather than leaving files that never merge; record enabling the units on a streamed install as follow-up work. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Revised over six rounds against the code. Summary of what changed and why. Design gaps
Incorrect claims
Prerequisites found in existing code
Scope Disk streaming is out: it would place the files but |
Review findings had been folded in as prose, leaving most points stated once and then re-justified. Cuts about a quarter of the text with no change to any decision, constraint or cited behaviour. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Prose down from 6691 to 3907 words across two passes. Drops the redundant consumer diagram and trims the example to one entry per array. No decision, constraint or cited behaviour changed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep path optional for Trident-managed placement, describe current defaults and the unresolved slotted-policy selection from RFC 0838. Remove repeated rationale while retaining schema, update, rollback and validation rules. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a required per-entry id matching the DDI's SYSEXT_ID or CONFEXT_ID, with duplicate and mismatch validation. Match extension updates by kind and ID; use the compressed hash to detect replacement. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Description
RFC for carrying sysext and confext images inside COSI. Each entry requires an
idmatching the DDI'sSYSEXT_IDorCONFEXT_ID, reusesImageFile, and may omitpathfor Trident-managed placement.🤔 Rationale
Bundle extensions with the OS and identify updates by
(kind, id)rather than by filename or hash.📝 Checks
git diff --check— passed. No code tests run (RFC only).📌 Follow-ups
🗒️ Notes
Older Trident versions silently omit bundled extensions; see the RFC's versioning section.