Skip to content

feat(layout): let an add_partitions entry carry its own mkfs options - #347

Open
ci-robbot wants to merge 1 commit into
mudler:masterfrom
ci-robbot:bot/5476-layout-mkfs-options
Open

ci-robbot wants to merge 1 commit into
mudler:masterfrom
ci-robbot:bot/5476-layout-mkfs-options

Conversation

@ci-robbot

Copy link
Copy Markdown
Contributor

Refs: kairos-io/kairos#5476

Summary

MkfsCall already appends customOpts in buildOptions, on both the linux and the fat branch, but nothing could set them: formatPartition hardcoded customOpts: []string{} and schema.Partition had no field to read one from. A layout stage could pick the filesystem and its label, and no other mkfs flag was reachable.

This adds mkfs_options to schema.Partition, carries it into the internal Partition the format pass uses, and hands it to MkfsCall. Position is the one the existing code already chose: after the label flag, before the device.

The case that prompted it: Kairos creates ext4 filesystems with -O ^metadata_csum_seed, because an older e2fsprogs cannot mount a filesystem carrying that feature. Go code in the kairos monorepo passes it through its own partitioner, but a partition created by a yip layout: stage cannot, so the two paths produce different ext4 filesystems. The two call sites are immucore/internal/utils/partitions.go (the kairos.ram.create_partitions path) and the /oem/01_reset.yaml stage.

Nothing changes for a partition that does not set the field: it is omitempty, and a nil slice leaves buildOptions on the path it takes today.

How it was tested

go test ./pkg/plugins/ ./pkg/schema/, with the mkfs tools shimmed onto PATH (this box has none, and Apply does exec.LookPath before running).

  • pkg/plugins, layout label: 37 passed / 0 failed, including three new specs that pin the rendered command line: the ext branch (mkfs.ext4 -L COS_OEM -O ^metadata_csum_seed <dev>), the fat branch (mkfs.fat -n COS_GRUB -F 32 <dev>), and a partition with no fsLabel, which pins the option position when the label flag is absent. The mock console fails on any unregistered command, so these assert the exact string.
  • pkg/schema: 11 passed / 0 failed, including a new spec that loads mkfs_options from YAML, so the user-facing key is pinned and not just the Go field.
  • Regression proof: on a throwaway copy with only the formatPartition line reverted to []string{}, all three layout specs fail and the rest still pass. The wiring is load-bearing.

gofmt is clean on every file I touched. pkg/schema/schema_test.go is listed by gofmt -l both here and on master (a space-indented comment at line 206 that predates this branch); I left it alone rather than mix a reformat into this diff.

Not covered: a real mkfs run. The suite mocks the console, so this proves the argument vector, not what mkfs does with it.

MkfsCall already honours customOpts in buildOptions, on both the linux
and the fat branch, but nothing could ever set them: formatPartition
hardcoded an empty slice and schema.Partition had no field to read one
from. So a layout stage could choose the filesystem and its label and
nothing else, and every mkfs flag beyond -L / -n was out of reach.

That is a real gap, not a theoretical one. Kairos has to create ext4
filesystems with -O ^metadata_csum_seed, because an older e2fsprogs
cannot mount a filesystem that carries that feature. Go code in the
kairos monorepo does it through its own partitioner, but partitions
created by a yip layout stage cannot, so the two paths disagree about
what an ext4 filesystem looks like.

Add mkfs_options to schema.Partition, carry it into the internal
Partition the format pass works on, and hand it to MkfsCall as the
custom options it was already prepared to append. Position is the one
the existing code chose: after the label flag, before the device, which
is where mkfs wants its options.

Nothing changes for a partition that does not set it: the field is
omitempty and a nil slice leaves buildOptions on the path it takes
today.

Signed-off-by: Ettore Di Giacinto <mudler@kairos.io>
jimmykarily pushed a commit to kairos-io/AuroraBoot that referenced this pull request Oct 26, 2026
The first-boot reset config of raw disk images creates COS_PERSISTENT
with LinuxImgFs (ext2). That constant is meant for the active/passive/
recovery image files; partitions use LinuxFs (ext4), as kairos-agent
install does.

On ext2 the persistent data (k3s/etcd, containerd, kubelet) has no
journal and no extents, which makes unpacking images slow, stalls etcd
fsync and leaves the filesystem inconsistent after a crash.

COS_STATE stays ext2 for now. GRUB reads it on every boot, and yip's
layout mkfs cannot pass -O ^metadata_csum_seed yet, so an image with
e2fsprogs 1.47+ and a GRUB older than 2.12 without the backport would
fail to boot (kairos-io/kairos#5476, mudler/yip#347).

Signed-off-by: Kai Ehrhardt <ehrhardt.kai@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

2 participants