Skip to content

Multi kernel support#45

Merged
mergify[bot] merged 3 commits intotinkerbell:mainfrom
jacobweinstock:multi-kernel-support
Mar 8, 2026
Merged

Multi kernel support#45
mergify[bot] merged 3 commits intotinkerbell:mainfrom
jacobweinstock:multi-kernel-support

Conversation

@jacobweinstock
Copy link
Copy Markdown
Member

Description

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

Multi-version kernel builds need config files namespaced by kernel
branch. Rename config/defconfig.{arch} to kernel.configs/{major}.{minor}.y.{arch}
and add 6.19.y configs.

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

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds multi-kernel support to the CaptainOS build pipeline by selecting per-branch defconfigs from kernel.configs/, version-scoping build outputs/artifact names by kernel_version, and updating CI/docs accordingly.

Changes:

  • Introduces kernel.configs/{major}.{minor}.y.{arch} defconfig selection and adds new 6.19.y configs.
  • Versions mkosi outputs and out/ artifacts (vmlinuz/initramfs/iso/checksums) by kernel_version, updating QEMU/OCI/release/clean flows.
  • Updates CI to detect the default kernel version from captain/config.py and adjusts cache paths/artifact paths.

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
kernel.configs/6.19.y.arm64 Adds new arm64 defconfig for 6.19.y stable branch.
kernel.configs/6.19.y.amd64 Adds new amd64 defconfig for 6.19.y stable branch.
kernel.configs/6.18.y.arm64 Updates header/comments for the existing 6.18.y arm64 defconfig.
kernel.configs/6.18.y.amd64 Updates header/comments for the existing 6.18.y amd64 defconfig.
docs/kernel-build.md Documents the kernel build pipeline and (intended) multi-version defconfig layout.
captain/qemu.py Makes QEMU test boot pick versioned out/ artifacts.
captain/oci.py Includes kernel_version in collected artifact naming/paths for OCI publishing.
captain/kernel.py Auto-selects defconfigs based on kernel stable branch; stores resolved configs under kernel.configs/.
captain/iso.py Versions ISO output filename by kernel_version.
captain/docker.py Forwards KERNEL_CONFIG override into the builder container.
captain/config.py Introduces DEFAULT_KERNEL_VERSION; versions mkosi output directories by kernel version.
captain/cli.py Plumbs kernel flags into more subcommands; versions mkosi initramfs paths; adds per-version clean behavior.
captain/artifacts.py Versions out/ artifact filenames by kernel_version.
README.md Updates build description/default kernel version and defconfig location.
.gitignore Ignores resolved configs under kernel.configs/.
.github/workflows/ci.yml Detects default kernel version dynamically; updates cache paths and artifact paths.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

A single build tree can now build and manage multiple kernel versions.
Key changes:
- DEFAULT_KERNEL_VERSION constant as single source of truth in config.py
- --kernel-version / KERNEL_VERSION on all subcommands (build, kernel,
  initramfs, iso, checksums, release, summary, qemu-test, clean)
- --kernel-config / KERNEL_CONFIG to override defconfig auto-detection
- Versioned output paths: mkosi.output/{stage}/{version}/{arch}/
- Versioned artifact names: vmlinuz-{ver}-{arch}, initramfs-{ver}-{arch}
- clean defaults to per-version cleanup; --all for full cleanup
- Improved qemu-test error messages showing missing files and version
- CI workflow updated to extract and propagate kernel version
- Resolved kernel config filename includes branch for no conflicts

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

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jacobweinstock jacobweinstock requested a review from Copilot March 8, 2026 21:57
Copy link
Copy Markdown

Copilot AI left a comment

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.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

captain/cli.py:1366

  • mkosi passthrough (unknown command safety-net) only passes the tools extra-tree. This will produce an initramfs without kernel modules (and differs from the initramfs/summary stages which pass both tools and modules). Add the modules extra-tree here as well for both docker and native paths.
        mlog = for_stage("mkosi")
        tools_tree = str(cfg.tools_output)
        output_dir = str(cfg.initramfs_output)
        match cfg.mkosi_mode:
            case "docker":
                docker.build_builder(cfg, logger=mlog)
                container_tree = f"/work/mkosi.output/tools/{cfg.arch}"
                container_outdir = f"/work/mkosi.output/initramfs/{cfg.kernel_version}/{cfg.arch}"
                docker.run_mkosi(
                    cfg,
                    f"--extra-tree={container_tree}",
                    f"--output-dir={container_outdir}",
                    command,

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Reorganise the mkosi.output directory so kernel artifacts (vmlinuz and
modules) and userspace tools (containerd, runc, nerdctl, CNI plugins)
live in cleanly separated, versioned paths.

Before:
  mkosi.output/
    extra-tree/{arch}/          # mixed: kernel modules + tools
    vmlinuz/{version}/{arch}/   # kernel image only

After:
  mkosi.output/
    tools/{arch}/               # tools only
    kernel/{version}/{arch}/    # kernel image + modules
      vmlinuz-{kver}
      modules/usr/lib/modules/{kver}/

Key changes:

- Rename vmlinuz/ → kernel/ and store both vmlinuz and modules under
  kernel/{version}/{arch}/.  The modules/ subtree mirrors a root
  filesystem layout (usr/lib/modules/{kver}/) so mkosi can consume it
  directly as --extra-tree.

- Rename extra-tree/ → tools/.  Now that kernel modules are stored
  separately, the directory only contains userspace tools, so the name
  should describe its content rather than leak mkosi implementation
  jargon.

- Pass two --extra-tree= flags to mkosi (tools + modules) instead of
  one combined tree.

- kernel.build() no longer wipes the tools directory on rebuild — it
  only cleans its own kernel/{version}/{arch}/ output.

- Remove the .kernel-{arch}-version marker file — the kernel version is
  now encoded in the directory path itself.

- Update CI workflow cache/artifact paths to match the new layout.

Config property renames:
  vmlinuz_output   → kernel_output
  extra_tree_output → tools_output
  (new)              modules_output

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

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

captain/artifacts.py:50

  • The docstring still mentions mkosi.output/initramfs/{arch}/, but cfg.initramfs_output is now versioned (mkosi.output/initramfs/{kernel_version}/{arch}). Update the docstring to reflect the actual output layout.
def collect_initramfs(cfg: Config, logger: StageLogger | None = None) -> None:
    """Copy the initramfs CPIO from mkosi.output/initramfs/{arch}/ to out/."""

captain/artifacts.py:65

  • collect_iso()'s docstring still refers to mkosi.output/iso/{arch}/, but cfg.iso_output is now versioned (mkosi.output/iso/{kernel_version}/{arch}). Adjust the docstring to avoid sending readers to the wrong path.
def collect_iso(cfg: Config, logger: StageLogger | None = None) -> None:
    """Copy the ISO image from mkosi.output/iso/{arch}/ to out/."""
    _log = logger or _default_log

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jacobweinstock jacobweinstock added the ready-to-merge Signal Mergify to merge the PR label Mar 8, 2026
@mergify mergify bot added the queued label Mar 8, 2026
mergify bot added a commit that referenced this pull request Mar 8, 2026
@mergify
Copy link
Copy Markdown
Contributor

mergify bot commented Mar 8, 2026

Merge Queue Status

Rule: default


This pull request spent 11 minutes 51 seconds in the queue, including 11 minutes 42 seconds running CI.

Required conditions to merge
  • #changes-requested-reviews-by=0
  • base=main
  • check-success=DCO
  • check-success=build-initramfs (amd64)
  • check-success=build-initramfs (arm64)
  • check-success=build-iso (amd64)
  • check-success=build-iso (arm64)
  • check-success=build-kernel (amd64)
  • check-success=build-kernel (arm64)
  • check-success=download-tools (amd64)
  • check-success=download-tools (arm64)
  • label!=do-not-merge
  • label=ready-to-merge
  • queue-position>=0
  • any of:
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = build-initramfs (amd64)
    • check-neutral = build-initramfs (amd64)
    • check-skipped = build-initramfs (amd64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = build-initramfs (arm64)
    • check-neutral = build-initramfs (arm64)
    • check-skipped = build-initramfs (arm64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = build-kernel (amd64)
    • check-neutral = build-kernel (amd64)
    • check-skipped = build-kernel (amd64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = build-kernel (arm64)
    • check-neutral = build-kernel (arm64)
    • check-skipped = build-kernel (arm64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = download-tools (amd64)
    • check-neutral = download-tools (amd64)
    • check-skipped = download-tools (amd64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = download-tools (arm64)
    • check-neutral = download-tools (arm64)
    • check-skipped = download-tools (arm64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = build-iso (amd64)
    • check-neutral = build-iso (amd64)
    • check-skipped = build-iso (amd64)
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = build-iso (arm64)
    • check-neutral = build-iso (arm64)
    • check-skipped = build-iso (arm64)

@mergify mergify bot merged commit d5d690f into tinkerbell:main Mar 8, 2026
20 checks passed
@mergify mergify bot removed the queued label Mar 8, 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