Skip to content

cidata: add GrubFix enum + structured runcmd/write_files on SeedSpec #203

@olofj

Description

@olofj

Part of #202.

Summary

Add the plumbing for per-distro GRUB fixups in the cidata seed without changing behavior for any current image. All KNOWN_IMAGES entries default to GrubFix::None; flipping them lands in the follow-up.

Changes

src/image.rs:

  • Add GrubFix enum:
    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
    pub enum GrubFix {
        None,
        GrubDefaultDropIn,   // /etc/default/grub.d/ is sourced + update-grub
        GrubDefaultInPlace,  // edit /etc/default/grub + grub2-mkconfig
    }
  • Add grub_fix: GrubFix field on KnownImage; default all rows to GrubFix::None for now.
  • Thread known.grub_fix through ensure_cidata_seed into the SeedSpec it constructs.

src/cloud_init.rs:

  • Add structured fields on SeedSpec so bhx-injected entries don't have to ride on extra_user_data:
    pub runcmd: Vec<Vec<String>>,
    pub write_files: Vec<WriteFile>,
    pub grub_fix: GrubFix,
  • Extend render_user_data to emit single runcmd: and write_files: blocks built from those structured fields. extra_user_data continues to be appended verbatim — cloud-init's documented list_extend merge for duplicate top-level list keys should concat operator-supplied runcmd: onto bhx's, but verify in Issue C before claiming this works.
  • Private helper per GrubFix variant that emits the right runcmd + write_files entries:
    • GrubDefaultDropIn: write /etc/default/grub.d/99-bhx-console.cfg containing GRUB_CMDLINE_LINUX=\"\$GRUB_CMDLINE_LINUX console=hvc0\", GRUB_TIMEOUT_STYLE=menu, GRUB_TIMEOUT=5; runcmd [update-grub]. Use YAML block scalar (|) for the content to sidestep quoting.
    • GrubDefaultInPlace: runcmd seds /etc/default/grub to append console=hvc0 to GRUB_CMDLINE_LINUX, set GRUB_TIMEOUT_STYLE=menu, set GRUB_TIMEOUT=5; then grub2-mkconfig -o /boot/grub2/grub.cfg.

src/profile.rs:

  • Only if it constructs SeedSpec literals — default the new fields to empty / GrubFix::None.

Footguns / notes for the implementer

  • console=hvc0 must be appended, not prepended: the kernel's /dev/console symlink follows the last console= argument.
  • Don't wrap the runcmd in set -e. grub2-mkconfig exits non-zero on benign os-prober failures.
  • One-line comment on the runcmd that it runs late enough for /boot to be mounted — anyone tempted to move this to bootcmd "to be earlier" will silently break images with a separate /boot partition.

Test plan (hardware-free)

  • Unit test: render SeedSpec for each GrubFix variant; assert generated YAML matches a fixture string.
  • Unit test: combine structured runcmd with operator-supplied extra_user_data; parse the resulting YAML and confirm both runcmd: blocks are well-formed.
  • cargo fmt --check, cargo clippy --all-targets -- -D warnings, cargo test clean.

Acceptance

  • CI gates clean.
  • No KNOWN_IMAGES entry changes behavior (all stay GrubFix::None).
  • Renderer emits one runcmd: and one write_files: block; YAML round-trips through serde_yaml or equivalent without errors.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions