Skip to content

Find the bootstrap slot by its sector headers: - #77

Merged
mergify[bot] merged 2 commits into
tinkerbell:mainfrom
jacobweinstock:bootstrap-slot-headers
Oct 15, 2026
Merged

mergify[bot] merged 2 commits into
tinkerbell:mainfrom
jacobweinstock:bootstrap-slot-headers

Conversation

@jacobweinstock

Copy link
Copy Markdown
Member

Description

Tinkerbell needed a layout file published with every ISO to find the slot. Fetching, caching and keeping that file in step with the ISO, across redirects and ISOs replaced in place, was where most of Tinkerbell's complexity and failure modes came from.

Every sector of the slot now starts with a header identifying it, so Tinkerbell finds the slot in the bytes it serves, as it already does the kernel arguments, and no layout file is published. Each header is an empty cpio archive, so an ISO served unmodified still boots.

The build checks that the slot is stored intact and sector aligned, and that nothing else in the ISO looks like one of its headers. An ISO that fails the check is removed, and an existing ISO is only reused when it passes.

Fixes: #

How Has This Been Tested?

How are existing users impacted? What migration steps/scripts do we need?

Checklist:

I have:

  • updated the documentation and/or roadmap (if required)
  • added unit or e2e tests
  • provided instructions on how to upgrade

Tinkerbell needed a layout file published with every ISO to find the
slot. Fetching, caching and keeping that file in step with the ISO,
across redirects and ISOs replaced in place, was where most of
Tinkerbell's complexity and failure modes came from.

Every sector of the slot now starts with a header identifying it, so
Tinkerbell finds the slot in the bytes it serves, as it already does
the kernel arguments, and no layout file is published. Each header is
an empty cpio archive, so an ISO served unmodified still boots.

The build checks that the slot is stored intact and sector aligned,
and that nothing else in the ISO looks like one of its headers. An
ISO that fails the check is removed, and an existing ISO is only
reused when it passes.

Signed-off-by: Jacob Weinstock <jakobweinstock@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Interrupted builds can leave incomplete ISOs that pass slot validation and are subsequently reused.

1 open finding
What changed in this PR

Replaces bootstrap-slot layout sidecars with sector headers so Tinkerbell can locate the slot directly in ISO bytes.

Changes:

  • Adds sector headers and validates slot integrity, alignment, and uniqueness.
  • Validates existing ISOs before reuse.
  • Removes layout sidecars from artifact collection and CI uploads.
File Description
captain/​iso.py Generates sector headers and validates bootstrap slots.
captain/​flavor.py Removes layout sidecars from artifact listings.
captain/​cli/​stages.py Checks slots before reusing existing ISOs.
captain/​artifacts.py Stops collecting layout sidecars.
.github/​workflows/​ci.yml Uploads only the ISO artifact.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread captain/iso.py Outdated
grub-mkrescue wrote straight to the final path, so a build that failed
or was interrupted after writing the bootstrap slot left a truncated ISO
whose slot still passes the check, and a later build reused it. Build
and check the ISO under a .partial name and move it into place only when
both succeed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Jacob Weinstock <jakobweinstock@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The boot-format change needs end-to-end confirmation of Tinkerbell compatibility and unmodified ISO boot behavior.

0 open findings

1 resolved since last review

🧠 Review effort: Balanced

@jacobweinstock jacobweinstock added the ready-to-merge Signal Mergify to merge the PR label Oct 15, 2026
@mergify mergify Bot added the queued label Oct 15, 2026
@mergify

mergify Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Merge Queue Status

  • ✅ Entered queue — 2026-10-15 22:13 UTC · Rule: default · triggered by rule refactored queue action rule
  • ✅ Checks passed · on draft merge queue: checking #77 on main (9ccacb2) #78
  • ✅ Merged — 2026-10-15 22:39 UTC · at d68689a6d2e69b22d20db6ef6fc206bd7d58af6e · merge

This pull request spent 26 minutes 2 seconds in the queue, including 25 minutes 15 seconds running CI.

Required conditions to merge
  • #changes-requested-reviews-by=0
  • base=main
  • check-success=DCO
  • check-success=build-captainos (with kernel) trixie-slim (amd64)
  • check-success=build-captainos (with kernel) trixie-slim (arm64)
  • check-success=build-captainos trixie-armbian-rpi (arm64)
  • check-success=build-captainos trixie-full (amd64)
  • check-success=build-captainos trixie-full (arm64)
  • check-success=build-captainos trixie-genio (arm64)
  • check-success=build-captainos trixie-meson64 (arm64)
  • check-success=build-captainos trixie-rockchip64 (arm64)
  • check-success=build-captainos trixie-rockchip64-vendor (arm64)
  • check-success=build-captainos-kernel (amd64)
  • check-success=build-captainos-kernel (arm64)
  • check-success=build-dockerfile (amd64)
  • check-success=build-dockerfile (arm64)
  • check-success=download-tools (amd64)
  • check-success=download-tools (arm64)
  • check-success=prepare
  • github-review-approved [🛡 GitHub repository ruleset rule main]
  • label!=do-not-merge
  • label=ready-to-merge
  • queue-position>=0
  • any of:
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/download-tools (amd64)
    • check-neutral = @github-actions/download-tools (amd64)
    • check-skipped = @github-actions/download-tools (amd64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/download-tools (arm64)
    • check-neutral = @github-actions/download-tools (arm64)
    • check-skipped = @github-actions/download-tools (arm64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/build-captainos (with kernel) trixie-slim (amd64)
    • check-neutral = @github-actions/build-captainos (with kernel) trixie-slim (amd64)
    • check-skipped = @github-actions/build-captainos (with kernel) trixie-slim (amd64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/build-captainos (with kernel) trixie-slim (arm64)
    • check-neutral = @github-actions/build-captainos (with kernel) trixie-slim (arm64)
    • check-skipped = @github-actions/build-captainos (with kernel) trixie-slim (arm64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/build-captainos trixie-armbian-rpi (arm64)
    • check-neutral = @github-actions/build-captainos trixie-armbian-rpi (arm64)
    • check-skipped = @github-actions/build-captainos trixie-armbian-rpi (arm64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/build-captainos trixie-full (amd64)
    • check-neutral = @github-actions/build-captainos trixie-full (amd64)
    • check-skipped = @github-actions/build-captainos trixie-full (amd64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/build-captainos trixie-full (arm64)
    • check-neutral = @github-actions/build-captainos trixie-full (arm64)
    • check-skipped = @github-actions/build-captainos trixie-full (arm64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/build-captainos trixie-genio (arm64)
    • check-neutral = @github-actions/build-captainos trixie-genio (arm64)
    • check-skipped = @github-actions/build-captainos trixie-genio (arm64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/build-captainos trixie-meson64 (arm64)
    • check-neutral = @github-actions/build-captainos trixie-meson64 (arm64)
    • check-skipped = @github-actions/build-captainos trixie-meson64 (arm64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/build-captainos trixie-rockchip64 (arm64)
    • check-neutral = @github-actions/build-captainos trixie-rockchip64 (arm64)
    • check-skipped = @github-actions/build-captainos trixie-rockchip64 (arm64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/build-captainos trixie-rockchip64-vendor (arm64)
    • check-neutral = @github-actions/build-captainos trixie-rockchip64-vendor (arm64)
    • check-skipped = @github-actions/build-captainos trixie-rockchip64-vendor (arm64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/build-captainos-kernel (amd64)
    • check-neutral = @github-actions/build-captainos-kernel (amd64)
    • check-skipped = @github-actions/build-captainos-kernel (amd64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/prepare
    • check-neutral = @github-actions/prepare
    • check-skipped = @github-actions/prepare
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/build-dockerfile (amd64)
    • check-neutral = @github-actions/build-dockerfile (amd64)
    • check-skipped = @github-actions/build-dockerfile (amd64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/build-dockerfile (arm64)
    • check-neutral = @github-actions/build-dockerfile (arm64)
    • check-skipped = @github-actions/build-dockerfile (arm64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = @github-actions/build-captainos-kernel (arm64)
    • check-neutral = @github-actions/build-captainos-kernel (arm64)
    • check-skipped = @github-actions/build-captainos-kernel (arm64)

@mergify
mergify Bot merged commit d68689a into tinkerbell:main Oct 15, 2026
22 checks passed
@jacobweinstock
jacobweinstock deleted the bootstrap-slot-headers branch October 15, 2026 22:39
@mergify mergify Bot removed the queued label Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Signal Mergify to merge the PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants