all:
  children:
    zuul_unreachable:
      hosts: {}
  hosts:
    debian-bookworm:
      ansible_connection: ssh
      ansible_host: 2a13:1a81:8000:3124:f816:3eff:fe55:73f
      ansible_port: 22
      ansible_python_interpreter: auto
      ansible_user: zuul
      nodepool:
        az: nova
        cloud: regiocloud-a-ci
        external_id: 62083c3c-0d1e-425b-af7a-14efe6c67ecc
        host_id: 4ba4344415ca7057d9956ea5de826bbc0b830981e82c0e0f191fa07b
        interface_ip: 2a13:1a81:8000:3124:f816:3eff:fe55:73f
        label: debian-bookworm
        node_properties: {}
        private_ipv4: 10.128.7.31
        private_ipv6: null
        provider: regiocloud-a
        public_ipv4: 81.163.192.13
        public_ipv6: 2a13:1a81:8000:3124:f816:3eff:fe55:73f
        region: null
        slot: null
  vars:
    zuul:
      _inheritance_path:
      - '<Job base explicit: None implied: {MatchAny:{ImpliedBranchMatcher:main}}
        source: osism/zuul-config/zuul.d/jobs.yaml@main#2>'
      - '<Job flake8 explicit: None implied: {MatchAny:{ImpliedBranchMatcher:main}}
        source: osism/zuul-jobs/.zuul.yaml@main#32>'
      - '<Job flake8 explicit: None implied: None source: osism/k8s-capi-images/.zuul.yaml@main#10>'
      ansible_version: '9'
      attempts: 1
      branch: main
      build: 3fe12764d4d2444d8358f086d4199f05
      build_refs:
      - branch: main
        change: '335'
        change_message: "Stand up a DIB-based local build with functional parity to
          image-builder\n\nCloses #333\n\n## Summary\n\nReplaces the Packer/image-builder
          local build with a `disk-image-create`-based build that produces the same
          `ubuntu-2404-kube-vX.YY` qcow2 images. A custom `k8s-capi` DIB element fetches
          `kubernetes-sigs/image-builder` at a pinned git ref, installs Ansible in
          the chroot, and runs image-builder's own roles unchanged \u2014 `node`\u2192`setup`,
          `providers`, `containerd`, `kubernetes`, `sysprep` \u2014 in their original
          order, rather than reimplementing them in Bash.\n\nThe core problem this
          solves: image-builder's roles assume a booted VM, but the DIB chroot has
          no running systemd. The element supplies build-time shims prepended to `PATH`
          only during the Ansible run, plus a `policy-rc.d` during apt phases, so
          daemon-touching tasks succeed while still writing their config files. For
          the Kubernetes image pre-pull, containerd is started manually in the chroot
          so images bake into the offline content store, then stopped.\n\n## Change
          set (commit order)\n\n1. **`a01d8ab` Pin diskimage-builder in requirements.txt**
          \u2014 Establishes the `diskimage-builder` toolchain pin the build depends
          on, mirroring the version used across OSISM image repositories.\n\n2. **`784a31b`
          Add k8s-capi DIB element scaffold and metadata** \u2014 The element skeleton:
          `package-installs.yaml` dependencies for the in-chroot Ansible run, the
          two `DIB_*` inputs (`environment.d/10-k8s-capi.bash`) selecting the image-builder
          ref and the per-series override, `element-deps`, and a `README.rst` documenting
          the element, its shim mechanism, and the manual containerd pre-pull.\n\n3.
          **`b17c3f6` Add systemd-less build shims for k8s-capi element** \u2014 The
          six shims prepended to `PATH` during the Ansible run (`static/shims/`).
          The `systemctl` shim performs `enable`/`disable` offline and no-ops daemon
          lifecycle/status verbs; `modprobe`, `sysctl`, `journalctl`, `fstrim`, and
          `udevadm` are no-ops, so the roles still write their config files while
          the live kernel/daemon action is skipped.\n\n4. **`091a7a6` Add wrapper
          playbook running image-builder roles** \u2014 `static/wrapper.yml` mirrors
          image-builder's `node.yml` play header and runs its roles unchanged in order:
          `node` (which pulls in `setup`), `providers`, `containerd`, `kubernetes`,
          `sysprep`. A manual containerd start/wait/stop brackets the `kubernetes`
          role so kubeadm's offline image pre-pull bakes images into the content store
          in the systemd-less chroot.\n\n5. **`f6139a7` Fetch and stage image-builder
          in extra-data.d** \u2014 `extra-data.d/10-fetch-image-builder` clones `kubernetes-sigs/image-builder`
          at the pinned ref and stages its ansible tree, config JSONs, the wrapper,
          shims, and the selected override under `$TMP_HOOKS_PATH` for the chroot.
          The config JSONs are normalized by rewriting Packer `{{ user \\`x\\` }}`
          to Ansible `{{ x }}` and JSON `null` to `\"\"`, so a direct `ansible-playbook`
          run matches Packer's handling (`containerd_additional_settings` is b64decoded
          and would fail on `None`).\n\n6. **`060f6e9` Install Ansible and run image-builder
          in install.d** \u2014 `install.d/50-install-ansible` builds a throwaway
          venv with image-builder's pinned `ansible-core` plus the `community.general`/`ansible.posix`
          collections; `install.d/60-run-image-builder` runs `wrapper.yml` with the
          staged config JSONs and override. A `policy-rc.d` and the shims on `PATH`
          let daemon-touching tasks succeed in the chroot; the override is loaded
          last so its Kubernetes/containerd/runc versions win.\n\n7. **`6d2bbbf` Clean
          up build scaffolding in cleanup.d** \u2014 `cleanup.d/90-k8s-capi-cleanup`
          removes the `policy-rc.d`, the staged image-builder tree and venv, and the
          Ansible/pip caches so no build scaffolding ships in the image. The roles'
          own outputs (binaries, configs, pre-pulled images) live elsewhere on the
          root filesystem and are kept.\n\n8. **`b8a8673` Add per-series and gardener
          override files** \u2014 `overrides/` Kubernetes/gardener override files
          for each supported series (v1.33\u2013v1.36). Non-gardener files set the
          Kubernetes deb version, semver, and series; the `-gardener` variants also
          pin containerd 1.7.30 and runc 1.4.0. No ISO or output handling is included.\n\n9.
          **`e778d84` Replace build-local.sh with DIB local build** \u2014 Replaces
          the Packer wrapper with a `disk-image-create` build. It maps a `VERSION`
          argument (e.g. `v1.33` or `v1.36-gardener`) to an override, sets the `DIB_*`
          inputs, builds a venv from `requirements.txt`, and runs `disk-image-create`
          with the `ubuntu`/`vm`/`growroot`/`openssh-server`/`k8s-capi` elements to
          produce `ubuntu-2404-kube-<semver>` qcow2 images.\n\n## Notes on scope /
          divergence from the issue\n\n- Scope matches the issue: per-series overrides
          cover v1.33\u2013v1.36 and their gardener variants, with Kubernetes and
          gardener vars only \u2014 no ISO handling, no CI/publishing wiring (those
          are downstream of #332).\n- Parity is verified by booting in qemu or offline
          inspection of installed component versions, containerd/CNI/crictl/sysctl/modules
          config, and pre-pulled images; this PR stands up the build and does not
          itself add automated parity tests.\n\n---\n\n_Implemented by [planwerk-agent](https://github.com/planwerk/planwerk-agent)
          84299e2 with Claude:claude-opus-4-8_\n"
        change_url: https://github.com/osism/k8s-capi-images/pull/335
        commit_id: e778d84c2c7a3e838c6e512941f573a54e9f59d1
        patchset: e778d84c2c7a3e838c6e512941f573a54e9f59d1
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/k8s-capi-images
          name: osism/k8s-capi-images
          short_name: k8s-capi-images
        src_dir: src/github.com/osism/k8s-capi-images
        topic: null
      buildset: 48feea36015d4b66af5a29131b0538c7
      buildset_refs:
      - branch: main
        change: '335'
        change_message: "Stand up a DIB-based local build with functional parity to
          image-builder\n\nCloses #333\n\n## Summary\n\nReplaces the Packer/image-builder
          local build with a `disk-image-create`-based build that produces the same
          `ubuntu-2404-kube-vX.YY` qcow2 images. A custom `k8s-capi` DIB element fetches
          `kubernetes-sigs/image-builder` at a pinned git ref, installs Ansible in
          the chroot, and runs image-builder's own roles unchanged \u2014 `node`\u2192`setup`,
          `providers`, `containerd`, `kubernetes`, `sysprep` \u2014 in their original
          order, rather than reimplementing them in Bash.\n\nThe core problem this
          solves: image-builder's roles assume a booted VM, but the DIB chroot has
          no running systemd. The element supplies build-time shims prepended to `PATH`
          only during the Ansible run, plus a `policy-rc.d` during apt phases, so
          daemon-touching tasks succeed while still writing their config files. For
          the Kubernetes image pre-pull, containerd is started manually in the chroot
          so images bake into the offline content store, then stopped.\n\n## Change
          set (commit order)\n\n1. **`a01d8ab` Pin diskimage-builder in requirements.txt**
          \u2014 Establishes the `diskimage-builder` toolchain pin the build depends
          on, mirroring the version used across OSISM image repositories.\n\n2. **`784a31b`
          Add k8s-capi DIB element scaffold and metadata** \u2014 The element skeleton:
          `package-installs.yaml` dependencies for the in-chroot Ansible run, the
          two `DIB_*` inputs (`environment.d/10-k8s-capi.bash`) selecting the image-builder
          ref and the per-series override, `element-deps`, and a `README.rst` documenting
          the element, its shim mechanism, and the manual containerd pre-pull.\n\n3.
          **`b17c3f6` Add systemd-less build shims for k8s-capi element** \u2014 The
          six shims prepended to `PATH` during the Ansible run (`static/shims/`).
          The `systemctl` shim performs `enable`/`disable` offline and no-ops daemon
          lifecycle/status verbs; `modprobe`, `sysctl`, `journalctl`, `fstrim`, and
          `udevadm` are no-ops, so the roles still write their config files while
          the live kernel/daemon action is skipped.\n\n4. **`091a7a6` Add wrapper
          playbook running image-builder roles** \u2014 `static/wrapper.yml` mirrors
          image-builder's `node.yml` play header and runs its roles unchanged in order:
          `node` (which pulls in `setup`), `providers`, `containerd`, `kubernetes`,
          `sysprep`. A manual containerd start/wait/stop brackets the `kubernetes`
          role so kubeadm's offline image pre-pull bakes images into the content store
          in the systemd-less chroot.\n\n5. **`f6139a7` Fetch and stage image-builder
          in extra-data.d** \u2014 `extra-data.d/10-fetch-image-builder` clones `kubernetes-sigs/image-builder`
          at the pinned ref and stages its ansible tree, config JSONs, the wrapper,
          shims, and the selected override under `$TMP_HOOKS_PATH` for the chroot.
          The config JSONs are normalized by rewriting Packer `{{ user \\`x\\` }}`
          to Ansible `{{ x }}` and JSON `null` to `\"\"`, so a direct `ansible-playbook`
          run matches Packer's handling (`containerd_additional_settings` is b64decoded
          and would fail on `None`).\n\n6. **`060f6e9` Install Ansible and run image-builder
          in install.d** \u2014 `install.d/50-install-ansible` builds a throwaway
          venv with image-builder's pinned `ansible-core` plus the `community.general`/`ansible.posix`
          collections; `install.d/60-run-image-builder` runs `wrapper.yml` with the
          staged config JSONs and override. A `policy-rc.d` and the shims on `PATH`
          let daemon-touching tasks succeed in the chroot; the override is loaded
          last so its Kubernetes/containerd/runc versions win.\n\n7. **`6d2bbbf` Clean
          up build scaffolding in cleanup.d** \u2014 `cleanup.d/90-k8s-capi-cleanup`
          removes the `policy-rc.d`, the staged image-builder tree and venv, and the
          Ansible/pip caches so no build scaffolding ships in the image. The roles'
          own outputs (binaries, configs, pre-pulled images) live elsewhere on the
          root filesystem and are kept.\n\n8. **`b8a8673` Add per-series and gardener
          override files** \u2014 `overrides/` Kubernetes/gardener override files
          for each supported series (v1.33\u2013v1.36). Non-gardener files set the
          Kubernetes deb version, semver, and series; the `-gardener` variants also
          pin containerd 1.7.30 and runc 1.4.0. No ISO or output handling is included.\n\n9.
          **`e778d84` Replace build-local.sh with DIB local build** \u2014 Replaces
          the Packer wrapper with a `disk-image-create` build. It maps a `VERSION`
          argument (e.g. `v1.33` or `v1.36-gardener`) to an override, sets the `DIB_*`
          inputs, builds a venv from `requirements.txt`, and runs `disk-image-create`
          with the `ubuntu`/`vm`/`growroot`/`openssh-server`/`k8s-capi` elements to
          produce `ubuntu-2404-kube-<semver>` qcow2 images.\n\n## Notes on scope /
          divergence from the issue\n\n- Scope matches the issue: per-series overrides
          cover v1.33\u2013v1.36 and their gardener variants, with Kubernetes and
          gardener vars only \u2014 no ISO handling, no CI/publishing wiring (those
          are downstream of #332).\n- Parity is verified by booting in qemu or offline
          inspection of installed component versions, containerd/CNI/crictl/sysctl/modules
          config, and pre-pulled images; this PR stands up the build and does not
          itself add automated parity tests.\n\n---\n\n_Implemented by [planwerk-agent](https://github.com/planwerk/planwerk-agent)
          84299e2 with Claude:claude-opus-4-8_\n"
        change_url: https://github.com/osism/k8s-capi-images/pull/335
        commit_id: e778d84c2c7a3e838c6e512941f573a54e9f59d1
        patchset: e778d84c2c7a3e838c6e512941f573a54e9f59d1
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/k8s-capi-images
          name: osism/k8s-capi-images
          short_name: k8s-capi-images
        src_dir: src/github.com/osism/k8s-capi-images
        topic: null
      change: '335'
      change_message: "Stand up a DIB-based local build with functional parity to
        image-builder\n\nCloses #333\n\n## Summary\n\nReplaces the Packer/image-builder
        local build with a `disk-image-create`-based build that produces the same
        `ubuntu-2404-kube-vX.YY` qcow2 images. A custom `k8s-capi` DIB element fetches
        `kubernetes-sigs/image-builder` at a pinned git ref, installs Ansible in the
        chroot, and runs image-builder's own roles unchanged \u2014 `node`\u2192`setup`,
        `providers`, `containerd`, `kubernetes`, `sysprep` \u2014 in their original
        order, rather than reimplementing them in Bash.\n\nThe core problem this solves:
        image-builder's roles assume a booted VM, but the DIB chroot has no running
        systemd. The element supplies build-time shims prepended to `PATH` only during
        the Ansible run, plus a `policy-rc.d` during apt phases, so daemon-touching
        tasks succeed while still writing their config files. For the Kubernetes image
        pre-pull, containerd is started manually in the chroot so images bake into
        the offline content store, then stopped.\n\n## Change set (commit order)\n\n1.
        **`a01d8ab` Pin diskimage-builder in requirements.txt** \u2014 Establishes
        the `diskimage-builder` toolchain pin the build depends on, mirroring the
        version used across OSISM image repositories.\n\n2. **`784a31b` Add k8s-capi
        DIB element scaffold and metadata** \u2014 The element skeleton: `package-installs.yaml`
        dependencies for the in-chroot Ansible run, the two `DIB_*` inputs (`environment.d/10-k8s-capi.bash`)
        selecting the image-builder ref and the per-series override, `element-deps`,
        and a `README.rst` documenting the element, its shim mechanism, and the manual
        containerd pre-pull.\n\n3. **`b17c3f6` Add systemd-less build shims for k8s-capi
        element** \u2014 The six shims prepended to `PATH` during the Ansible run
        (`static/shims/`). The `systemctl` shim performs `enable`/`disable` offline
        and no-ops daemon lifecycle/status verbs; `modprobe`, `sysctl`, `journalctl`,
        `fstrim`, and `udevadm` are no-ops, so the roles still write their config
        files while the live kernel/daemon action is skipped.\n\n4. **`091a7a6` Add
        wrapper playbook running image-builder roles** \u2014 `static/wrapper.yml`
        mirrors image-builder's `node.yml` play header and runs its roles unchanged
        in order: `node` (which pulls in `setup`), `providers`, `containerd`, `kubernetes`,
        `sysprep`. A manual containerd start/wait/stop brackets the `kubernetes` role
        so kubeadm's offline image pre-pull bakes images into the content store in
        the systemd-less chroot.\n\n5. **`f6139a7` Fetch and stage image-builder in
        extra-data.d** \u2014 `extra-data.d/10-fetch-image-builder` clones `kubernetes-sigs/image-builder`
        at the pinned ref and stages its ansible tree, config JSONs, the wrapper,
        shims, and the selected override under `$TMP_HOOKS_PATH` for the chroot. The
        config JSONs are normalized by rewriting Packer `{{ user \\`x\\` }}` to Ansible
        `{{ x }}` and JSON `null` to `\"\"`, so a direct `ansible-playbook` run matches
        Packer's handling (`containerd_additional_settings` is b64decoded and would
        fail on `None`).\n\n6. **`060f6e9` Install Ansible and run image-builder in
        install.d** \u2014 `install.d/50-install-ansible` builds a throwaway venv
        with image-builder's pinned `ansible-core` plus the `community.general`/`ansible.posix`
        collections; `install.d/60-run-image-builder` runs `wrapper.yml` with the
        staged config JSONs and override. A `policy-rc.d` and the shims on `PATH`
        let daemon-touching tasks succeed in the chroot; the override is loaded last
        so its Kubernetes/containerd/runc versions win.\n\n7. **`6d2bbbf` Clean up
        build scaffolding in cleanup.d** \u2014 `cleanup.d/90-k8s-capi-cleanup` removes
        the `policy-rc.d`, the staged image-builder tree and venv, and the Ansible/pip
        caches so no build scaffolding ships in the image. The roles' own outputs
        (binaries, configs, pre-pulled images) live elsewhere on the root filesystem
        and are kept.\n\n8. **`b8a8673` Add per-series and gardener override files**
        \u2014 `overrides/` Kubernetes/gardener override files for each supported
        series (v1.33\u2013v1.36). Non-gardener files set the Kubernetes deb version,
        semver, and series; the `-gardener` variants also pin containerd 1.7.30 and
        runc 1.4.0. No ISO or output handling is included.\n\n9. **`e778d84` Replace
        build-local.sh with DIB local build** \u2014 Replaces the Packer wrapper with
        a `disk-image-create` build. It maps a `VERSION` argument (e.g. `v1.33` or
        `v1.36-gardener`) to an override, sets the `DIB_*` inputs, builds a venv from
        `requirements.txt`, and runs `disk-image-create` with the `ubuntu`/`vm`/`growroot`/`openssh-server`/`k8s-capi`
        elements to produce `ubuntu-2404-kube-<semver>` qcow2 images.\n\n## Notes
        on scope / divergence from the issue\n\n- Scope matches the issue: per-series
        overrides cover v1.33\u2013v1.36 and their gardener variants, with Kubernetes
        and gardener vars only \u2014 no ISO handling, no CI/publishing wiring (those
        are downstream of #332).\n- Parity is verified by booting in qemu or offline
        inspection of installed component versions, containerd/CNI/crictl/sysctl/modules
        config, and pre-pulled images; this PR stands up the build and does not itself
        add automated parity tests.\n\n---\n\n_Implemented by [planwerk-agent](https://github.com/planwerk/planwerk-agent)
        84299e2 with Claude:claude-opus-4-8_\n"
      change_url: https://github.com/osism/k8s-capi-images/pull/335
      child_jobs: []
      commit_id: e778d84c2c7a3e838c6e512941f573a54e9f59d1
      event_id: f2bad240-7261-11f1-9409-2ae44b24f71d
      executor:
        hostname: 521e9411259a
        inventory_file: /var/lib/zuul/builds/3fe12764d4d2444d8358f086d4199f05/ansible/inventory.yaml
        log_root: /var/lib/zuul/builds/3fe12764d4d2444d8358f086d4199f05/work/logs
        result_data_file: /var/lib/zuul/builds/3fe12764d4d2444d8358f086d4199f05/work/results.json
        src_root: /var/lib/zuul/builds/3fe12764d4d2444d8358f086d4199f05/work/src
        work_root: /var/lib/zuul/builds/3fe12764d4d2444d8358f086d4199f05/work
      include_vars: []
      items:
      - branch: main
        change: '335'
        change_message: "Stand up a DIB-based local build with functional parity to
          image-builder\n\nCloses #333\n\n## Summary\n\nReplaces the Packer/image-builder
          local build with a `disk-image-create`-based build that produces the same
          `ubuntu-2404-kube-vX.YY` qcow2 images. A custom `k8s-capi` DIB element fetches
          `kubernetes-sigs/image-builder` at a pinned git ref, installs Ansible in
          the chroot, and runs image-builder's own roles unchanged \u2014 `node`\u2192`setup`,
          `providers`, `containerd`, `kubernetes`, `sysprep` \u2014 in their original
          order, rather than reimplementing them in Bash.\n\nThe core problem this
          solves: image-builder's roles assume a booted VM, but the DIB chroot has
          no running systemd. The element supplies build-time shims prepended to `PATH`
          only during the Ansible run, plus a `policy-rc.d` during apt phases, so
          daemon-touching tasks succeed while still writing their config files. For
          the Kubernetes image pre-pull, containerd is started manually in the chroot
          so images bake into the offline content store, then stopped.\n\n## Change
          set (commit order)\n\n1. **`a01d8ab` Pin diskimage-builder in requirements.txt**
          \u2014 Establishes the `diskimage-builder` toolchain pin the build depends
          on, mirroring the version used across OSISM image repositories.\n\n2. **`784a31b`
          Add k8s-capi DIB element scaffold and metadata** \u2014 The element skeleton:
          `package-installs.yaml` dependencies for the in-chroot Ansible run, the
          two `DIB_*` inputs (`environment.d/10-k8s-capi.bash`) selecting the image-builder
          ref and the per-series override, `element-deps`, and a `README.rst` documenting
          the element, its shim mechanism, and the manual containerd pre-pull.\n\n3.
          **`b17c3f6` Add systemd-less build shims for k8s-capi element** \u2014 The
          six shims prepended to `PATH` during the Ansible run (`static/shims/`).
          The `systemctl` shim performs `enable`/`disable` offline and no-ops daemon
          lifecycle/status verbs; `modprobe`, `sysctl`, `journalctl`, `fstrim`, and
          `udevadm` are no-ops, so the roles still write their config files while
          the live kernel/daemon action is skipped.\n\n4. **`091a7a6` Add wrapper
          playbook running image-builder roles** \u2014 `static/wrapper.yml` mirrors
          image-builder's `node.yml` play header and runs its roles unchanged in order:
          `node` (which pulls in `setup`), `providers`, `containerd`, `kubernetes`,
          `sysprep`. A manual containerd start/wait/stop brackets the `kubernetes`
          role so kubeadm's offline image pre-pull bakes images into the content store
          in the systemd-less chroot.\n\n5. **`f6139a7` Fetch and stage image-builder
          in extra-data.d** \u2014 `extra-data.d/10-fetch-image-builder` clones `kubernetes-sigs/image-builder`
          at the pinned ref and stages its ansible tree, config JSONs, the wrapper,
          shims, and the selected override under `$TMP_HOOKS_PATH` for the chroot.
          The config JSONs are normalized by rewriting Packer `{{ user \\`x\\` }}`
          to Ansible `{{ x }}` and JSON `null` to `\"\"`, so a direct `ansible-playbook`
          run matches Packer's handling (`containerd_additional_settings` is b64decoded
          and would fail on `None`).\n\n6. **`060f6e9` Install Ansible and run image-builder
          in install.d** \u2014 `install.d/50-install-ansible` builds a throwaway
          venv with image-builder's pinned `ansible-core` plus the `community.general`/`ansible.posix`
          collections; `install.d/60-run-image-builder` runs `wrapper.yml` with the
          staged config JSONs and override. A `policy-rc.d` and the shims on `PATH`
          let daemon-touching tasks succeed in the chroot; the override is loaded
          last so its Kubernetes/containerd/runc versions win.\n\n7. **`6d2bbbf` Clean
          up build scaffolding in cleanup.d** \u2014 `cleanup.d/90-k8s-capi-cleanup`
          removes the `policy-rc.d`, the staged image-builder tree and venv, and the
          Ansible/pip caches so no build scaffolding ships in the image. The roles'
          own outputs (binaries, configs, pre-pulled images) live elsewhere on the
          root filesystem and are kept.\n\n8. **`b8a8673` Add per-series and gardener
          override files** \u2014 `overrides/` Kubernetes/gardener override files
          for each supported series (v1.33\u2013v1.36). Non-gardener files set the
          Kubernetes deb version, semver, and series; the `-gardener` variants also
          pin containerd 1.7.30 and runc 1.4.0. No ISO or output handling is included.\n\n9.
          **`e778d84` Replace build-local.sh with DIB local build** \u2014 Replaces
          the Packer wrapper with a `disk-image-create` build. It maps a `VERSION`
          argument (e.g. `v1.33` or `v1.36-gardener`) to an override, sets the `DIB_*`
          inputs, builds a venv from `requirements.txt`, and runs `disk-image-create`
          with the `ubuntu`/`vm`/`growroot`/`openssh-server`/`k8s-capi` elements to
          produce `ubuntu-2404-kube-<semver>` qcow2 images.\n\n## Notes on scope /
          divergence from the issue\n\n- Scope matches the issue: per-series overrides
          cover v1.33\u2013v1.36 and their gardener variants, with Kubernetes and
          gardener vars only \u2014 no ISO handling, no CI/publishing wiring (those
          are downstream of #332).\n- Parity is verified by booting in qemu or offline
          inspection of installed component versions, containerd/CNI/crictl/sysctl/modules
          config, and pre-pulled images; this PR stands up the build and does not
          itself add automated parity tests.\n\n---\n\n_Implemented by [planwerk-agent](https://github.com/planwerk/planwerk-agent)
          84299e2 with Claude:claude-opus-4-8_\n"
        change_url: https://github.com/osism/k8s-capi-images/pull/335
        commit_id: e778d84c2c7a3e838c6e512941f573a54e9f59d1
        patchset: e778d84c2c7a3e838c6e512941f573a54e9f59d1
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/k8s-capi-images
          name: osism/k8s-capi-images
          short_name: k8s-capi-images
          src_dir: src/github.com/osism/k8s-capi-images
        topic: null
      job: flake8
      jobtags: []
      max_attempts: 3
      message: U3RhbmQgdXAgYSBESUItYmFzZWQgbG9jYWwgYnVpbGQgd2l0aCBmdW5jdGlvbmFsIHBhcml0eSB0byBpbWFnZS1idWlsZGVyCgpDbG9zZXMgIzMzMwoKIyMgU3VtbWFyeQoKUmVwbGFjZXMgdGhlIFBhY2tlci9pbWFnZS1idWlsZGVyIGxvY2FsIGJ1aWxkIHdpdGggYSBgZGlzay1pbWFnZS1jcmVhdGVgLWJhc2VkIGJ1aWxkIHRoYXQgcHJvZHVjZXMgdGhlIHNhbWUgYHVidW50dS0yNDA0LWt1YmUtdlguWVlgIHFjb3cyIGltYWdlcy4gQSBjdXN0b20gYGs4cy1jYXBpYCBESUIgZWxlbWVudCBmZXRjaGVzIGBrdWJlcm5ldGVzLXNpZ3MvaW1hZ2UtYnVpbGRlcmAgYXQgYSBwaW5uZWQgZ2l0IHJlZiwgaW5zdGFsbHMgQW5zaWJsZSBpbiB0aGUgY2hyb290LCBhbmQgcnVucyBpbWFnZS1idWlsZGVyJ3Mgb3duIHJvbGVzIHVuY2hhbmdlZCDigJQgYG5vZGVg4oaSYHNldHVwYCwgYHByb3ZpZGVyc2AsIGBjb250YWluZXJkYCwgYGt1YmVybmV0ZXNgLCBgc3lzcHJlcGAg4oCUIGluIHRoZWlyIG9yaWdpbmFsIG9yZGVyLCByYXRoZXIgdGhhbiByZWltcGxlbWVudGluZyB0aGVtIGluIEJhc2guCgpUaGUgY29yZSBwcm9ibGVtIHRoaXMgc29sdmVzOiBpbWFnZS1idWlsZGVyJ3Mgcm9sZXMgYXNzdW1lIGEgYm9vdGVkIFZNLCBidXQgdGhlIERJQiBjaHJvb3QgaGFzIG5vIHJ1bm5pbmcgc3lzdGVtZC4gVGhlIGVsZW1lbnQgc3VwcGxpZXMgYnVpbGQtdGltZSBzaGltcyBwcmVwZW5kZWQgdG8gYFBBVEhgIG9ubHkgZHVyaW5nIHRoZSBBbnNpYmxlIHJ1biwgcGx1cyBhIGBwb2xpY3ktcmMuZGAgZHVyaW5nIGFwdCBwaGFzZXMsIHNvIGRhZW1vbi10b3VjaGluZyB0YXNrcyBzdWNjZWVkIHdoaWxlIHN0aWxsIHdyaXRpbmcgdGhlaXIgY29uZmlnIGZpbGVzLiBGb3IgdGhlIEt1YmVybmV0ZXMgaW1hZ2UgcHJlLXB1bGwsIGNvbnRhaW5lcmQgaXMgc3RhcnRlZCBtYW51YWxseSBpbiB0aGUgY2hyb290IHNvIGltYWdlcyBiYWtlIGludG8gdGhlIG9mZmxpbmUgY29udGVudCBzdG9yZSwgdGhlbiBzdG9wcGVkLgoKIyMgQ2hhbmdlIHNldCAoY29tbWl0IG9yZGVyKQoKMS4gKipgYTAxZDhhYmAgUGluIGRpc2tpbWFnZS1idWlsZGVyIGluIHJlcXVpcmVtZW50cy50eHQqKiDigJQgRXN0YWJsaXNoZXMgdGhlIGBkaXNraW1hZ2UtYnVpbGRlcmAgdG9vbGNoYWluIHBpbiB0aGUgYnVpbGQgZGVwZW5kcyBvbiwgbWlycm9yaW5nIHRoZSB2ZXJzaW9uIHVzZWQgYWNyb3NzIE9TSVNNIGltYWdlIHJlcG9zaXRvcmllcy4KCjIuICoqYDc4NGEzMWJgIEFkZCBrOHMtY2FwaSBESUIgZWxlbWVudCBzY2FmZm9sZCBhbmQgbWV0YWRhdGEqKiDigJQgVGhlIGVsZW1lbnQgc2tlbGV0b246IGBwYWNrYWdlLWluc3RhbGxzLnlhbWxgIGRlcGVuZGVuY2llcyBmb3IgdGhlIGluLWNocm9vdCBBbnNpYmxlIHJ1biwgdGhlIHR3byBgRElCXypgIGlucHV0cyAoYGVudmlyb25tZW50LmQvMTAtazhzLWNhcGkuYmFzaGApIHNlbGVjdGluZyB0aGUgaW1hZ2UtYnVpbGRlciByZWYgYW5kIHRoZSBwZXItc2VyaWVzIG92ZXJyaWRlLCBgZWxlbWVudC1kZXBzYCwgYW5kIGEgYFJFQURNRS5yc3RgIGRvY3VtZW50aW5nIHRoZSBlbGVtZW50LCBpdHMgc2hpbSBtZWNoYW5pc20sIGFuZCB0aGUgbWFudWFsIGNvbnRhaW5lcmQgcHJlLXB1bGwuCgozLiAqKmBiMTdjM2Y2YCBBZGQgc3lzdGVtZC1sZXNzIGJ1aWxkIHNoaW1zIGZvciBrOHMtY2FwaSBlbGVtZW50Kiog4oCUIFRoZSBzaXggc2hpbXMgcHJlcGVuZGVkIHRvIGBQQVRIYCBkdXJpbmcgdGhlIEFuc2libGUgcnVuIChgc3RhdGljL3NoaW1zL2ApLiBUaGUgYHN5c3RlbWN0bGAgc2hpbSBwZXJmb3JtcyBgZW5hYmxlYC9gZGlzYWJsZWAgb2ZmbGluZSBhbmQgbm8tb3BzIGRhZW1vbiBsaWZlY3ljbGUvc3RhdHVzIHZlcmJzOyBgbW9kcHJvYmVgLCBgc3lzY3RsYCwgYGpvdXJuYWxjdGxgLCBgZnN0cmltYCwgYW5kIGB1ZGV2YWRtYCBhcmUgbm8tb3BzLCBzbyB0aGUgcm9sZXMgc3RpbGwgd3JpdGUgdGhlaXIgY29uZmlnIGZpbGVzIHdoaWxlIHRoZSBsaXZlIGtlcm5lbC9kYWVtb24gYWN0aW9uIGlzIHNraXBwZWQuCgo0LiAqKmAwOTFhN2E2YCBBZGQgd3JhcHBlciBwbGF5Ym9vayBydW5uaW5nIGltYWdlLWJ1aWxkZXIgcm9sZXMqKiDigJQgYHN0YXRpYy93cmFwcGVyLnltbGAgbWlycm9ycyBpbWFnZS1idWlsZGVyJ3MgYG5vZGUueW1sYCBwbGF5IGhlYWRlciBhbmQgcnVucyBpdHMgcm9sZXMgdW5jaGFuZ2VkIGluIG9yZGVyOiBgbm9kZWAgKHdoaWNoIHB1bGxzIGluIGBzZXR1cGApLCBgcHJvdmlkZXJzYCwgYGNvbnRhaW5lcmRgLCBga3ViZXJuZXRlc2AsIGBzeXNwcmVwYC4gQSBtYW51YWwgY29udGFpbmVyZCBzdGFydC93YWl0L3N0b3AgYnJhY2tldHMgdGhlIGBrdWJlcm5ldGVzYCByb2xlIHNvIGt1YmVhZG0ncyBvZmZsaW5lIGltYWdlIHByZS1wdWxsIGJha2VzIGltYWdlcyBpbnRvIHRoZSBjb250ZW50IHN0b3JlIGluIHRoZSBzeXN0ZW1kLWxlc3MgY2hyb290LgoKNS4gKipgZjYxMzlhN2AgRmV0Y2ggYW5kIHN0YWdlIGltYWdlLWJ1aWxkZXIgaW4gZXh0cmEtZGF0YS5kKiog4oCUIGBleHRyYS1kYXRhLmQvMTAtZmV0Y2gtaW1hZ2UtYnVpbGRlcmAgY2xvbmVzIGBrdWJlcm5ldGVzLXNpZ3MvaW1hZ2UtYnVpbGRlcmAgYXQgdGhlIHBpbm5lZCByZWYgYW5kIHN0YWdlcyBpdHMgYW5zaWJsZSB0cmVlLCBjb25maWcgSlNPTnMsIHRoZSB3cmFwcGVyLCBzaGltcywgYW5kIHRoZSBzZWxlY3RlZCBvdmVycmlkZSB1bmRlciBgJFRNUF9IT09LU19QQVRIYCBmb3IgdGhlIGNocm9vdC4gVGhlIGNvbmZpZyBKU09OcyBhcmUgbm9ybWFsaXplZCBieSByZXdyaXRpbmcgUGFja2VyIGB7eyB1c2VyIFxgeFxgIH19YCB0byBBbnNpYmxlIGB7eyB4IH19YCBhbmQgSlNPTiBgbnVsbGAgdG8gYCIiYCwgc28gYSBkaXJlY3QgYGFuc2libGUtcGxheWJvb2tgIHJ1biBtYXRjaGVzIFBhY2tlcidzIGhhbmRsaW5nIChgY29udGFpbmVyZF9hZGRpdGlvbmFsX3NldHRpbmdzYCBpcyBiNjRkZWNvZGVkIGFuZCB3b3VsZCBmYWlsIG9uIGBOb25lYCkuCgo2LiAqKmAwNjBmNmU5YCBJbnN0YWxsIEFuc2libGUgYW5kIHJ1biBpbWFnZS1idWlsZGVyIGluIGluc3RhbGwuZCoqIOKAlCBgaW5zdGFsbC5kLzUwLWluc3RhbGwtYW5zaWJsZWAgYnVpbGRzIGEgdGhyb3dhd2F5IHZlbnYgd2l0aCBpbWFnZS1idWlsZGVyJ3MgcGlubmVkIGBhbnNpYmxlLWNvcmVgIHBsdXMgdGhlIGBjb21tdW5pdHkuZ2VuZXJhbGAvYGFuc2libGUucG9zaXhgIGNvbGxlY3Rpb25zOyBgaW5zdGFsbC5kLzYwLXJ1bi1pbWFnZS1idWlsZGVyYCBydW5zIGB3cmFwcGVyLnltbGAgd2l0aCB0aGUgc3RhZ2VkIGNvbmZpZyBKU09OcyBhbmQgb3ZlcnJpZGUuIEEgYHBvbGljeS1yYy5kYCBhbmQgdGhlIHNoaW1zIG9uIGBQQVRIYCBsZXQgZGFlbW9uLXRvdWNoaW5nIHRhc2tzIHN1Y2NlZWQgaW4gdGhlIGNocm9vdDsgdGhlIG92ZXJyaWRlIGlzIGxvYWRlZCBsYXN0IHNvIGl0cyBLdWJlcm5ldGVzL2NvbnRhaW5lcmQvcnVuYyB2ZXJzaW9ucyB3aW4uCgo3LiAqKmA2ZDJiYmJmYCBDbGVhbiB1cCBidWlsZCBzY2FmZm9sZGluZyBpbiBjbGVhbnVwLmQqKiDigJQgYGNsZWFudXAuZC85MC1rOHMtY2FwaS1jbGVhbnVwYCByZW1vdmVzIHRoZSBgcG9saWN5LXJjLmRgLCB0aGUgc3RhZ2VkIGltYWdlLWJ1aWxkZXIgdHJlZSBhbmQgdmVudiwgYW5kIHRoZSBBbnNpYmxlL3BpcCBjYWNoZXMgc28gbm8gYnVpbGQgc2NhZmZvbGRpbmcgc2hpcHMgaW4gdGhlIGltYWdlLiBUaGUgcm9sZXMnIG93biBvdXRwdXRzIChiaW5hcmllcywgY29uZmlncywgcHJlLXB1bGxlZCBpbWFnZXMpIGxpdmUgZWxzZXdoZXJlIG9uIHRoZSByb290IGZpbGVzeXN0ZW0gYW5kIGFyZSBrZXB0LgoKOC4gKipgYjhhODY3M2AgQWRkIHBlci1zZXJpZXMgYW5kIGdhcmRlbmVyIG92ZXJyaWRlIGZpbGVzKiog4oCUIGBvdmVycmlkZXMvYCBLdWJlcm5ldGVzL2dhcmRlbmVyIG92ZXJyaWRlIGZpbGVzIGZvciBlYWNoIHN1cHBvcnRlZCBzZXJpZXMgKHYxLjMz4oCTdjEuMzYpLiBOb24tZ2FyZGVuZXIgZmlsZXMgc2V0IHRoZSBLdWJlcm5ldGVzIGRlYiB2ZXJzaW9uLCBzZW12ZXIsIGFuZCBzZXJpZXM7IHRoZSBgLWdhcmRlbmVyYCB2YXJpYW50cyBhbHNvIHBpbiBjb250YWluZXJkIDEuNy4zMCBhbmQgcnVuYyAxLjQuMC4gTm8gSVNPIG9yIG91dHB1dCBoYW5kbGluZyBpcyBpbmNsdWRlZC4KCjkuICoqYGU3NzhkODRgIFJlcGxhY2UgYnVpbGQtbG9jYWwuc2ggd2l0aCBESUIgbG9jYWwgYnVpbGQqKiDigJQgUmVwbGFjZXMgdGhlIFBhY2tlciB3cmFwcGVyIHdpdGggYSBgZGlzay1pbWFnZS1jcmVhdGVgIGJ1aWxkLiBJdCBtYXBzIGEgYFZFUlNJT05gIGFyZ3VtZW50IChlLmcuIGB2MS4zM2Agb3IgYHYxLjM2LWdhcmRlbmVyYCkgdG8gYW4gb3ZlcnJpZGUsIHNldHMgdGhlIGBESUJfKmAgaW5wdXRzLCBidWlsZHMgYSB2ZW52IGZyb20gYHJlcXVpcmVtZW50cy50eHRgLCBhbmQgcnVucyBgZGlzay1pbWFnZS1jcmVhdGVgIHdpdGggdGhlIGB1YnVudHVgL2B2bWAvYGdyb3dyb290YC9gb3BlbnNzaC1zZXJ2ZXJgL2BrOHMtY2FwaWAgZWxlbWVudHMgdG8gcHJvZHVjZSBgdWJ1bnR1LTI0MDQta3ViZS08c2VtdmVyPmAgcWNvdzIgaW1hZ2VzLgoKIyMgTm90ZXMgb24gc2NvcGUgLyBkaXZlcmdlbmNlIGZyb20gdGhlIGlzc3VlCgotIFNjb3BlIG1hdGNoZXMgdGhlIGlzc3VlOiBwZXItc2VyaWVzIG92ZXJyaWRlcyBjb3ZlciB2MS4zM+KAk3YxLjM2IGFuZCB0aGVpciBnYXJkZW5lciB2YXJpYW50cywgd2l0aCBLdWJlcm5ldGVzIGFuZCBnYXJkZW5lciB2YXJzIG9ubHkg4oCUIG5vIElTTyBoYW5kbGluZywgbm8gQ0kvcHVibGlzaGluZyB3aXJpbmcgKHRob3NlIGFyZSBkb3duc3RyZWFtIG9mICMzMzIpLgotIFBhcml0eSBpcyB2ZXJpZmllZCBieSBib290aW5nIGluIHFlbXUgb3Igb2ZmbGluZSBpbnNwZWN0aW9uIG9mIGluc3RhbGxlZCBjb21wb25lbnQgdmVyc2lvbnMsIGNvbnRhaW5lcmQvQ05JL2NyaWN0bC9zeXNjdGwvbW9kdWxlcyBjb25maWcsIGFuZCBwcmUtcHVsbGVkIGltYWdlczsgdGhpcyBQUiBzdGFuZHMgdXAgdGhlIGJ1aWxkIGFuZCBkb2VzIG5vdCBpdHNlbGYgYWRkIGF1dG9tYXRlZCBwYXJpdHkgdGVzdHMuCgotLS0KCl9JbXBsZW1lbnRlZCBieSBbcGxhbndlcmstYWdlbnRdKGh0dHBzOi8vZ2l0aHViLmNvbS9wbGFud2Vyay9wbGFud2Vyay1hZ2VudCkgODQyOTllMiB3aXRoIENsYXVkZTpjbGF1ZGUtb3B1cy00LThfCg==
      patchset: e778d84c2c7a3e838c6e512941f573a54e9f59d1
      pipeline: check
      playbook_context:
        playbook_projects:
          trusted/project_0/github.com/osism/zuul-config:
            canonical_name: github.com/osism/zuul-config
            checkout: main
            commit: 71b711c422c10c242a8f785dc6d41ed9d12e9cd3
          trusted/project_1/github.com/osism/openinfra-zuul-jobs:
            canonical_name: github.com/osism/openinfra-zuul-jobs
            checkout: master
            commit: 242732586e2cba04d04867d3e302888c766bc231
          trusted/project_2/github.com/osism/zuul-jobs:
            canonical_name: github.com/osism/zuul-jobs
            checkout: main
            commit: 1d71e58c93442038e695a5d883d57a603182c7ae
          untrusted/project_0/github.com/osism/zuul-jobs:
            canonical_name: github.com/osism/zuul-jobs
            checkout: main
            commit: 1d71e58c93442038e695a5d883d57a603182c7ae
          untrusted/project_1/github.com/osism/zuul-config:
            canonical_name: github.com/osism/zuul-config
            checkout: main
            commit: 71b711c422c10c242a8f785dc6d41ed9d12e9cd3
          untrusted/project_2/github.com/osism/openinfra-zuul-jobs:
            canonical_name: github.com/osism/openinfra-zuul-jobs
            checkout: master
            commit: 242732586e2cba04d04867d3e302888c766bc231
        playbooks:
        - path: untrusted/project_0/github.com/osism/zuul-jobs/playbooks/flake8/run.yaml
          roles:
          - checkout: main
            checkout_description: zuul branch
            link_name: ansible/playbook_0/role_0/zuul-config
            link_target: untrusted/project_1/github.com/osism/zuul-config
            role_path: ansible/playbook_0/role_0/zuul-config/roles
          - checkout: master
            checkout_description: project default branch
            link_name: ansible/playbook_0/role_1/openinfra-zuul-jobs
            link_target: untrusted/project_2/github.com/osism/openinfra-zuul-jobs
            role_path: ansible/playbook_0/role_1/openinfra-zuul-jobs/roles
          - checkout: main
            checkout_description: playbook branch
            link_name: ansible/playbook_0/role_2/zuul-jobs
            link_target: untrusted/project_0/github.com/osism/zuul-jobs
            role_path: ansible/playbook_0/role_2/zuul-jobs/roles
      post_review: false
      post_timeout: 1800
      pre_timeout: null
      project:
        canonical_hostname: github.com
        canonical_name: github.com/osism/k8s-capi-images
        name: osism/k8s-capi-images
        short_name: k8s-capi-images
        src_dir: src/github.com/osism/k8s-capi-images
      projects:
        github.com/osism/k8s-capi-images:
          canonical_hostname: github.com
          canonical_name: github.com/osism/k8s-capi-images
          checkout: main
          checkout_description: zuul branch
          commit: 1c6385b437f3a353b75dc87988d207999a714141
          name: osism/k8s-capi-images
          required: false
          short_name: k8s-capi-images
          src_dir: src/github.com/osism/k8s-capi-images
      ref: refs/pull/335/head
      resources: {}
      tenant: osism
      timeout: 1800
      topic: null
      voting: true
