-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
distro: add OutputFilename
option to ImageOptions
#1039
base: main
Are you sure you want to change the base?
Conversation
This commit allows to change the filename when creating a manifest from an image type. This is useful when doing a UI for users, e.g. this will allow us to support: ``` $ image-builder build rhel-9 type:qcow2 --output foo.img ``` (this will also be useful for bootc-image-builder). Well, osbuild itself will still put it under a directory when doing main_cli.py:exports() but that is something orthogonal.
My suggestion is to instead move EDIT: |
Thanks for the suggestion - maybe I'm misunderstanding and/or I need to look more at this but it seems to me that the "target.Target" is a higher level concept on a different layer that is applied after the manifest creation (c.f. https://github.com/osbuild/osbuild-composer/blob/main/internal/cloudapi/v2/server.go#L163) and is more an "after-fact" concept (i.e. do something to the image after it was created with the fixed filename). I'm looking for a way to already encode the target filename in the generated manifest. It seems to me to me this and the target.ImageName are (mostly) orthogonal, i.e. this is strictly about the local filename that is encoded in the generated manifest. I also looked at the options in target.Target and it seems only the "ImageName" (OutputFilename in this PR) is useful, the others can be derived (like "Created") or have no meaning in the "generate-a-manifest" use-case (like "Uuid"). But maybe I'm missing something, happy to have a chat about how you envision this. |
} | ||
|
||
func (i *ImageOptions) Filename(imgType ImageType) string { | ||
if i.OutputFilename != "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, if we do this we will have to add validation here too, something like:
if filepath.Base(s) != s {
return fmt.Errorf("cannot use %q: only relative filenames supported", s)
}
if filepath.Clean(s) != s {
return fmt.Errorf("cannot use %q: only clean filenames supported", s)
}
and of course error handling which will make the diff a bit more annoying.
Something for the gitlab tests maybe? |
Do you really think it's worth moving it all here just for the image name? The output filename should definitely end up in the target, of course, but beyond that, I don't know if it makes sense for the whole I could be convinced that moving |
TL;DR; my biggest problem with this approach is that
While your point of view is definitely correct, I'm afraid both concepts will eventually be used to solve the same problem—generating an artifact with the user-provided name. The fact that one is a higher-level concept and the other is a lower-level concept becomes just an implementation detail hidden from the user. On a conceptual level, I don't think
I don't think we should modify manifests to generate files with the desired filename. If we do, we'll need to make this possible with any tool that generates the manifest (OTK or anything else). Instead, image definitions usually encode metadata about what each pipeline can produce if exported. Renaming the produced artifact afterward seems like a cleaner separation of functionality. I admit that your proposed change is simple, clean, and an easy way to achieve the functionality that you need in the FWIW, I don't think I may be overthinking this a bit, but I'm sure that we will find some middle ground. |
I get where you're coming from (I think) and I don't disagree. The way I see it (and please tell me if I'm going in a completely different direction from what you were thinking), we have two major categories of options: Reusable and one-off (or build-specific) options. Reusable options are the ones we put in blueprints. Package selection, users, kernel args, enabling services, etc, are valid for all sorts of image types and we generally consider that anything that goes in a blueprint can be reused for multiple builds across time, image types, distributions, even architectures. One-off options are things that are specific to a single build. The target image type, upload target, ostree commit source, ostree ref. Things like these originally came from the composer-cli command line arguments and later as extra properties in the build request in the API. This distinction was never really formalised (I don't think it was anyway) and we generally had an understanding that some things don't belong in a blueprint, so we'd make it a build option, or target option, or something similar. Maybe we should think about this distinction in these (or similar) terms and reflect it in the code as well. Also, perhaps we need a third category here: Options that have no effect on manifest generation (like the upload target), which would be options that are never passed to
I don't fully agree with this, though I see your point. I don't think it's a bad idea to modify a manifest to output a desired filename. That said, allow me to argue with myself about the two possible ways of thinking about this:
No. 2 is basically what osbuild-composer with composer-cli do today.
I think I'm coming around to the same conclusion. I certainly agree that "Target is [not] usable as it is implemented in osbuild-composer". But we should definitely think about this more generally and design something that will be useful for all the use cases we can expect going forward. |
This commit allows to change the filename when creating a manifest from an image type. This is useful when doing a UI for users, e.g. this will allow us to support:
(this will also be useful for bootc-image-builder).
Well, osbuild itself will still put it under a directory when doing main_cli.py:exports() but that is something orthogonal.
I couldn't find a good way to test this end-to-end though (without doing a full manifest with depsolve) because the various
DiskImage()
,EdgeCommitImage()
functions are assigned toImageType.method
so iterating over the image types will only give me the ability to run Manifest() which creates a manifest.Manifest but from there I cannot access any pipelines without producing a full osbuild manifest. Ideas welcome, I did test it via the "image-builder-cli" branch. Maybe I'm missing something but this area of the code might need some tweaks to make it more testable.P.S. I also explored an alternative approach that would allow to set the filename on the image type in (in https://github.com/osbuild/images/compare/main...mvo5:make-target-filename-setable?expand=1) but this one here feels slightly cleaner.