Multi-step builds

Aperta
#2,802 4 commenti 0 reazioni 1 assegnatario Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@achilleas-k ci sta già lavorando.

Dal 28/10/2026.

  • #2803 di @achilleas-k — aperta

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

discussion

Ideas for the UX/flow for multi-step builds.

Option 1

Current working idea:

  • Add prefetch command at the top level.
  • Add --manifest option to build command.
image-builder manifest [...] > manifest.json
image-builder prefetch --cache <cache> manifest.json
sudo image-builder build --cache <cache> --manifest manifest.json

Advantages:

  • Shared --cache option between prefetch and build has the same meaning and same defaults.
  • prefetch subcommand can get extra options for managing the download when needed.

Disadvantages:

  • Overloads the build command with a new option that makes the positional argument (the image type) illegal.
    • I think this is bad UX. Positional arguments are considered mandatory and we just made our only one an optional.
  • Information (metadata) sharing between commands is not yet solved.
    • We can put metadata in the manifest, but it feels wrong to have information unrelated to osbuild (like upload targets) in there.
    • We can sidecar it, but that means creating more files, so perhaps we should work on a directory (see Option 3).

Option 2

All new functionality under build.

image-builder manifest [...] > manifest.json
image-builder build --cache <cache> --prefetch --manifest manifest.json
sudo image-builder build --cache <cache> --manifest manifest.json

Advantages:

  • No new subcommands to figure out, implement, test, and reason about.

Disadvantages:

  • Required positional argument becomes optional (see Option 1 disadvantages).

Option 3

All under manifest:

  • Overload the manifest command with all the manifest-related capabilities.
  • Add sub-commands to manifest for the three steps.
  • Use working directory as a single argument to serve as a shared state directory.
image-builder manifest create [...] <workingdir>  # creates <workingdir>/manifest.json
image-builder manifest prefetch <workingdir>      # expects <workingdir>/manifest.json; creates <workingdir>/store
sudo image-builder manifest build <workingdir>    # expects <workingdir>/manifest.json; uses <workingdif>/store as osbuild store; creates <workingdir>/image

Advantages:

  • All manifest subcommands take the same argument, a path, and work on it.
  • Little-to-no internal knowledge required by the user.
  • manifest subcommand becomes toolbox for creating and using manifests.
  • We can put anything we need in the <workingdir> to share state between commands.
    • Export pipelines.
    • Metadata required for upload (target cloud).

Disadvantages:

  • Breaks existing manifest command.
    • Perhaps we can use a new top-level command?
  • Very different model and UX from any of the other commands.

Variations:

  • We could also go one step further and make image-builder manifest upload a separate command.
    • Renaming manifest to something else, like project (maybe?), would make more sense here.

Option 4

Overload manifest with new functionality:

  • Add state directory for sharing information.
  • Prefetch as part of manifest generation.
image-builder manifest --prefetch --output-directory <workingdir> [...]               # creates <workingdir>/manifest.json and <workingdir>/store
sudo image-builder build --manifest <workingdir>/manifest.json --cache <workingdir>/store

Advantages:

  • All operations that require an internet connection are under one command and happen in one step.
  • The same flow works with and without --prefetch; without it, the downloading happens during build like in normal cases.

Disadvantages:

  • Required positional argument becomes optional (see Option 1 disadvantages).
  • Requires user to know what's created in <workingdir> and how to pass the manifest and store to the build command.

Option 5

Shared working directory with all new subcommands.

image-builder init <workingdir>              # or maybe 'prepare'; creates <workingdir>/manifest.json and any sidecar info required
image-builder prefetch <workingdir>          # or 'fetch-sources'; expects <workingdir>/manifest.json and creates <workingdir>/store
sudo image-builder build-image <workingdir>  # avoid overloading 'build'; expects <workingdir>/manifest.json and sidecar info; creates <workingdir>/image
image-builder upload-image <workingdir>      # avoid overloading 'upload'; expects <workingdir>/image and sidecar info

Disadvantages:

  • The distinction between build and build-image (or upload and upload-image) is not obvious.

General principles:

  • Avoid violating CLI UX conventions and expectations.
    • Making a required positional argument optional based on a flag.
  • Do not rely on the user understanding system internals.
    • For example, a user should not be expected to know that image-builder [...] <path> creates <path>/<file> and that <path>/<file> must become input to a follow-up command.

Parts I like:

  • One single shared directory that gets carried through all steps and can be used to share state.
    • Thanks @ondrejbudai for this.

Parts I don't like:

  • Subcommands that don't do what the name means in some cases (e.g. build --prefetch does not build; manifest upload does not "upload a manifest").

Discussion

I'm really liking the working directory idea. I think we should use that even if we don't go with Option 3 for the single all-encompassing subcommand. It solves our metadata-sharing (state-sharing) problem elegantly and makes our intended use case (Konflux builds) easier to manage, without requiring any understanding on behalf of the user.

The overloading of the build command can be solved by adding a new subcommand for building a manifest (build-manifest instead of build, with the path to the manifest as a positional argument).

I think the only thing holding me back from going all in on Option 3 is finding a good name for the new command that conveys the meaning we want. I don't like project, because that implies something more long-term. Other ideas:

  • workspace: suggested by Gemini. I don't like it.
  • bundle: also suggested by Gemini. It could work, with appropriate subcommands.
  • manifest: becomes less relevant the further into the process you go.
    • image-builder manifest create <workingdir> makes sense, it creates a manifest in the working directory.
    • image-builder manifest prefetch <workingdir> kinda makes sense.
    • image-builder manifest build <workingdir> sounds okay to my ears, but maybe not for users (we use the phrase "build a manifest" constantly, but users don't).
    • image-builder manifest upload <workingdir> is weird.
  • image: becomes more relevant the further into the process you go.
    • image-builder image <???> <workingdir> to generate manifest (maybe init?).
    • image-builder image prefetch <workingdir> starts to make some sense, but still not 100%.
    • image-builder image build <workingdir> finally makes sense.
    • image-builder image upload <workingdir> also makes sense.

The other option I see is to use the idea of the <workingdir> but with an all new set of top-level commands (Option 5), but I think I prefer the idea of a single top-level command taking care of everything.

Lingua principale
Go
Stelle
86
Fork
115
Merge medio
2g 6h
PR unite (30g)
48

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di osbuild/image-builder

Tutte le issue di osbuild/image-builder

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.