Skip to content

RFC: slotted extension storage - #838

Open
Paco Huelsz (frhuelsz) wants to merge 27 commits into
mainfrom
user/frhuelsz/rfc-slotted-sysexts
Open

Paco Huelsz (frhuelsz) wants to merge 27 commits into
mainfrom
user/frhuelsz/rfc-slotted-sysexts

Conversation

@frhuelsz

@frhuelsz Paco Huelsz (frhuelsz) commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Proposes updating ACL's OS, sysexts and confext defaults together through A/B updates, with matching content on rollback and preserved user changes in /etc. Builds on #789 for COSI extension delivery; Image Customizer's authoring API remains a separate proposal.

>> Read formatted markdown here. <<

Paco Huelsz (frhuelsz) and others added 2 commits October 8, 2026 11:53
Adds a 'slotted' scope for sysexts/confexts, stored per A/B volume in a
configurable store (default /var/trident/sysexts) and activated via an
/etc/extensions symlink written during servicing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The A/B rollback path invokes no subsystems: automatic rollback is
firmware-driven and validate_boot only reconciles Host Status, while
manual_rollback::stage_rollback touches only the pcrlock policy. A symlink
written during servicing would therefore survive a rollback pointing at the
wrong slot.

Activation now resolves at boot from the booted volume, via a single
<store>/current flip ordered before systemd-sysext.service.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
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.

Paco Huelsz (frhuelsz) and others added 2 commits October 8, 2026 12:05
The Rust types are an implementation detail; the public surface is the Host
Configuration document.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The original premise was wrong. Trident does not place extensions on
non-slotted storage: validate_extension_images_locations already rejects any
extension directory not on an A/B volume. The real cost is that satisfying it
requires a dedicated A/B volume pair, which the reference config pays for with
four partitions and 2.4 GB, and which a layout whose only A/B volume is a
verity-sealed /usr cannot pay at all.

The proposal is now to relax that check: slot-scoping as a property of the
extension rather than of the partition table, satisfied by an A/B volume as
today or by a Trident-owned per-slot store.

Activation no longer needs a boot-time unit. The extensions subsystem gains
ManualRollbackAb in runs_on, and automatic rollback is corrected at commit via
systemd-sysext refresh; version matching keeps the intervening window absent
rather than wrong.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@frhuelsz Paco Huelsz (frhuelsz) changed the title RFC: slotted system extensions RFC: slotted extension storage Oct 9, 2026
Replaces the previous mechanism. Symlinks are no longer written by the
extensions subsystem into /var/lib/extensions during servicing; selection is
recomputed every boot into /run/extensions from the slot that actually booted.
That removes the ManualRollbackAb runs_on change and the commit-time repair,
since nothing persists a decision that a rollback could invalidate.

Corrections and additions from review:

- Before=systemd-sysext.service is the ordering edge. ensure-sysext.service
  carries BindsTo= and After=systemd-sysext.service, so it runs after the
  merge and is the wrong anchor.
- WantedBy= plus Before= does not fail closed; the merge unit needs a
  Requires= drop-in.
- Per-file symlinking cannot commit a set atomically.
- A store manifest replaces globbing, so absence is distinguishable from loss.
- Two-phase rollout, since a rollback slot may predate the loader.
- Documents why content matching alone is insufficient, and scopes slotted
  extensions to /usr and /opt because reordering the merge ahead of an /etc
  overlay would exhaust the kernel filesystem stacking budget.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Both halves resolve the booted slot and expose that slot's content before a
consumer reads it, and both must act before the /etc overlay is mounted in the
initrd. /run is bind-moved across switch-root, so the sysext symlinks written
there remain valid for the later merge in the real root. Resolving the slot
once means the two halves cannot disagree about which slot they came from, and
it removes the unit-ordering, condition and fail-closed problems a real-root
systemd unit carries.

/etc payloads are confext-format images mounted as additional lowerdirs on the
existing overlay, so /etc stays mutable on systemd 255. Keeping the confext
format rather than inventing a tarball means the artefact is already what
native systemd-confext consumes on 256 or later; Azure Linux 4.0 ships 258.4.
Payloads must declare ID=_any, because native mounting enforces
extension-release matching that the custom mount bypasses, and a concrete ID
would silently stop merging at the transition.

Adds a change inventory across the new component, Trident and ACL with
T-shirt estimates for design and implementation, plus suggested sequencing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
0789 was rewritten and now names this RFC in three places: the optional path
discussion, destination validation, and an open question asking how a bundled
extension requests slotted placement. This RFC now answers that question rather
than sitting beside it.

The common case is a COSI-bundled extension that is slot-scoped, since an
extension shipped with the OS image is already tied to it. An independently
hosted extension placed per slot is the unusual combination.

Removes what 0789 delivers: the invented manifest.json is replaced by 0789's
Deployed Extension Inventory, the store is keyed by (kind, id) instead of
filenames, and the effective set, resolved-placement validation, atomic staging
and SELinux check relocation are referenced rather than restated.

Adds scope: shared|slotted on both the COSI ExtensionImage and the Host
Configuration Extension, spelled identically so one concept has one name, and
mutually exclusive with path so placement never changes implicitly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@frhuelsz Paco Huelsz (frhuelsz) changed the title RFC: slotted extension storage RFC: slotted extension storage (builds on #789) Oct 14, 2026
'commit' already names the post-boot servicing operation in Trident, so using
it for the loader publishing its symlink set is a confusing collision. The
loader has no relationship to that operation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@frhuelsz
Paco Huelsz (frhuelsz) marked this pull request as ready for review October 20, 2026 21:19
Copilot AI balanced review requested due to automatic review settings October 20, 2026 21:19
@frhuelsz
Paco Huelsz (frhuelsz) requested a review from a team as a code owner October 20, 2026 21:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Early-boot recovery and unresolved rollback and /etc reconciliation contracts require human architectural review.

2 open issues
What changed in this PR

Proposes slot-specific extension storage so ACL can update and roll back OS extensions together while preserving user /etc changes.

Changes:

  • Defines managed storage, staging, activation and recovery contracts.
  • Adds a versioned manifest schema and architecture diagram.
  • Outlines compatibility requirements and validation gates.
File Description
docs/​Development/​RFCs/​0838-slotted-sysexts/​0838-slot-loader-manifest.schema.json Defines the loader manifest format.
docs/​Development/​RFCs/​0838-slotted-sysexts/​0838-managed-extensions-overview.svg Illustrates delivery and boot-time activation.
docs/​Development/​RFCs/​0838-slotted-sysexts.md Specifies the proposed lifecycle and integration design.

Review effort: Balanced

Comment on lines +332 to +338
The loader unit uses `Restart=no` and gains
`OnFailure=trident-slot-loader-recovery.service`. This new initrd-only recovery
unit uses `ConditionKernelCommandLine=trident.update_boot=1` and
`ConditionPathExists=/etc/initrd-release`, with `DefaultDependencies=no`.
It has no dependency on `/etc` assembly or Trident's datastore and runs with
a bounded timeout. Nonzero exits, crashes and timeouts take this path, not
just errors returned by the loader's main function.
"minLength": 1,
"not": {
"anyOf": [
{"enum": [".", ".."]},
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 20, 2026 21:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Early-boot recovery, rollback compatibility and unresolved /etc reconciliation require human architectural review.

2 open issues

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 20, 2026 21:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Early-boot recovery, rollback compatibility and unresolved /etc reconciliation require human architectural review.

2 open issues

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 20, 2026 22:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI balanced review requested due to automatic review settings October 21, 2026 17:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Early-boot recovery, shared-state rollback compatibility and /etc reconciliation need human architectural review.

2 open issues

Review effort: Balanced

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 21, 2026 17:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Early-boot recovery, shared-state rollback compatibility and unresolved /etc reconciliation need human architectural review.

2 open issues

Review effort: Balanced

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 21, 2026 23:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Early-boot recovery, shared-state rollback compatibility and unresolved /etc reconciliation need human architectural review.

2 open issues

Review effort: Balanced

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 22, 2026 00:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Early-boot recovery and unresolved /etc reconciliation and shared-state rollback contracts require human architectural review.

2 open issues

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 22, 2026 00:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The initialization-only mode contract conflicts with mode transitions required by the implementation plan and acceptance tests.

3 open issues

Review effort: Balanced

Comment on lines +635 to +636
Mode and managed-set changes initially use A/B servicing; alias spelling alone
does not trigger one. Preserve retained slots until the transition completes.
`slot-loader.pending` marker, then synchronize its directory before clearing
the Trident-owned extension directory, including interrupted-staging
leftovers.
3. Reserve space to stage the new extension files. Write temporary `.raw` files

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copilot is always pestering me about atomic operations ... i wonder if we don't want to create a tmp folder and rename it instead of doing this file-by-file?

##### Selecting extensions at boot

1. **Existing:** ACL mounts ROOT in the initrd.
2. **New:** `trident-slot-loader.service` runs after that mount. The loader

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"runs after that mount" ... do we also need to be sure to run before anything? or make that configurable?

\* Future developments, not part of the initial implementation.

The mode applies to both sysexts and confexts. In `managed`/`acl`, explicit Host
Configuration URL/OCI images join the COSI-provided extension set and use

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really want to support both url/oci images and COSI-provided for ACL? seems simpler to support either/or than combined.

Copilot AI balanced review requested due to automatic review settings October 24, 2026 00:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The metadata-only reuse contract must reconcile compressed COSI hashes with raw-image hashes before it can be implemented consistently.

4 open issues

Review effort: Balanced

Comment on lines +218 to +221
On subsequent updates, staging matches incoming metadata against these records
before downloading or extracting a payload. A match reuses the local DDI across
slots, sources or different compression without inspecting its inner files or
separately downloading the payload. Without a verified match, fetch and validate

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants