Skip to content

Latest commit

 

History

History
130 lines (93 loc) · 5.44 KB

File metadata and controls

130 lines (93 loc) · 5.44 KB

Contributing

For a high-level overview of the project, see README.md.

How Images Get Built

  1. Images and tool versions are defined in deps.yaml.
  2. Dockerfile templates live in internal/dockerfile/tmpl/ and are embedded into the generator binary at compile time.
  3. make generate renders the templates into dockerfiles/Dockerfile.* and updates images-lock.yaml.
  4. make verify ensures no uncommitted changes exist (run in CI).
  5. make push builds and pushes multi-arch images to GHCR.

Adding a New Tool

deps.yaml has two sections for tools:

  • universal: — tools installed in every image (e.g. cosign, gh). Add here if the tool should be universally available.
  • tools: — tools that are opt-in per image (e.g. govulncheck). Add here, then reference the tool name under the relevant image's tools: list.

Both require the same fields:

- name: mytool
  source: org/repo          # GitHub org/repo, or a full URL for static sources
  version: v1.2.3
  checksums:
    linux/amd64: "<sha256>"
    linux/arm64: "<sha256>"
  release:
    download_template: "mytool-{version}-{os}-{arch}.tar.gz"
    extract: "mytool"       # path of the binary inside the archive; omit for plain binaries

After editing, run make generate and commit the updated Dockerfiles.

Adding a Tool Family

Tool families allow multiple versions of a tool to coexist in the same image, with a runtime selector to choose which one is active. This is useful for tools like Helm where you might need to support both v3 and v4.

To add a tool family:

  1. Add multiple tools with the same family field in deps.yaml:
tools:
  - name: helmv3
    family: helm
    source: "https://get.helm.sh"
    version: v3.20.2
    checksums:
      linux/amd64: "<sha256>"
      linux/arm64: "<sha256>"
    release:
      download_template: "{source}/helm-{version}-{os}-{arch}.tar.gz"
      extract: "{os}-{arch}/helm"

  - name: helmv4
    family: helm
    family_default: true  # This version is active by default
    source: "https://get.helm.sh"
    version: v4.1.4
    checksums:
      linux/amd64: "<sha256>"
      linux/arm64: "<sha256>"
    release:
      download_template: "{source}/helm-{version}-{os}-{arch}.tar.gz"
      extract: "{os}-{arch}/helm"
  1. Run make generate. This will:

    • Create a select-{family}.sh script (e.g. select-helm.sh)
    • Add the family to the ci-select command
    • Set up the default symlink in /var/ci-tools/active/
  2. Users can then select a version using:

    • Environment variable: SELECT_HELM_VERSION=helmv3
    • Runtime command: ci-select helm helmv3 or select-helm helmv3

Only one tool in a family should have family_default: true.

Adding a New Go Version

  1. Add a new entry under images: in deps.yaml with the desired Go base image (e.g. registry.suse.com/bci/golang:1.X.Y@sha256:...) and a name like go1.X.
  2. Run make generate and commit the new Dockerfile.

Archive

When make generate detects that a dockerfiles/Dockerfile.<name> no longer has a corresponding image in deps.yaml, it moves the file to archive/Dockerfile.<name>.<YYYYMMDD-HHMMSS> (UTC). Commit the archived file alongside the removal in deps.yaml.

Local Development

# Generate Dockerfiles from templates and deps.yaml
make generate

# Build all images locally
make build

# Build and push to registry
make push REPO=ghcr.io/rancher/ci-image

# Run tests, generate, and build
make all

Development Workflow

Generated Dockerfiles are checked in to the repository — they are not built on-the-fly. The expected workflow for any change to deps.yaml or the templates is:

  1. Make your changes.
  2. Run make generate to regenerate dockerfiles/ and images-lock.yaml.
  3. Commit both the source changes and the generated output together.

make verify (run in CI) fails if there are uncommitted generated files, so a PR with stale output will not pass.

Generated Files

  • dockerfiles/Dockerfile.<name> — the rendered Dockerfile for each image. Do not edit these directly; edit the templates instead.
  • images-lock.yaml — a compiled index generated by make generate. Records the active image names, resolved base images, platforms, tool set, and resolved versions for latest-pinned tools. Do not edit manually.
  • archive/Dockerfile.<name>.<YYYYMMDD-HHMMSS> — when make generate detects that a Dockerfile no longer has a corresponding image in deps.yaml, it moves it here rather than deleting it. Commit these alongside any image removal.

Template System

Dockerfiles are generated by the Go program in main.go using Go's text/template package. The templates live in internal/dockerfile/tmpl/ and are embedded into the binary at compile time.

  • dockerfile.tmpl — root template that assembles a complete Dockerfile. It calls the component templates below via {{template ...}} and .Install.Render().
  • zypper.tmpl — renders the zypper install layer for system packages.
  • curl_binary.tmpl, curl_gzip.tmpl, curl_archive.tmpl — render the curl-based install layer for a tool, varying by download format (plain binary, .gz, or .tar.gz/.zip).

To change how Dockerfiles are structured, edit the relevant template. To add a new install format, add a new curl_<format>.tmpl and wire it up in internal/dockerfile/install.go.