-
Notifications
You must be signed in to change notification settings - Fork 6
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
cmd: implement manifest command #6
Conversation
cmd/image-builder/main.go
Outdated
@@ -69,6 +104,17 @@ operating sytsems like centos and RHEL with easy customizations support.`, | |||
listImagesCmd.Flags().String("output", "", "Output in a specific format (text, json)") | |||
rootCmd.AddCommand(listImagesCmd) | |||
|
|||
manifestCmd := &cobra.Command{ | |||
Use: "manifest <distro> <image-type> [<arch>]", |
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.
Would it be nicer if the architecture was a flag option (--arch
)?
That way we could make blueprint an optional positional argument, which I think would be a more common usage. Switching the arch would probably be less common.
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.
Thanks, that is an interesting idea. The reason for current layout is that it's designed to be copy/paste friendly from list-iamges
. I.e.
$ image-builder list-images
...
rhel-10.0 type:oci arch:x86_64
$ image-builder manifest rhel-10.0 type:oci arch:x86_64
...
so we could tweak the list output to
$ image-builder list-images
...
rhel-10.0 type:vhd --arch x86_64
rhel-10.0 type:vmdk --arch x86_64
rhel-10.0 type:oci --arch x86_64
$ image-builder manifest rhel-10.0 type:oci --arch x86_64
...
(which looks a bit uneven but not too bad and for scripts we provide --json output).
Or we could drop this property (copy/pastable). Or we make the third argument fuzzy, i.e. if it starts with "arch:" we consider it an architecture and otherwise its a blueprint. (or something else I forgot?)
WDYT?
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.
so we could tweak the list output to
$ image-builder list-images ... rhel-10.0 type:vhd --arch x86_64 rhel-10.0 type:vmdk --arch x86_64 rhel-10.0 type:oci --arch x86_64 $ image-builder manifest rhel-10.0 type:oci --arch x86_64 ...
Eeeeeeeh... no. That's too weird.
Or we could drop this property (copy/pastable).
It's a nice property but yes I don't think it's important enough to make the output of another command so unusual.
Or we make the third argument fuzzy, i.e. if it starts with "arch:" we consider it an architecture and otherwise its a blueprint.
Not a bad idea.
(or something else I forgot?)
Perhaps something more uniform?
$ image-builder list-images
...
distro:rhel-10.0 type:vhd arch:x86_64
distro:rhel-10.0 type:vmdk arch:x86_64
distro:rhel-10.0 type:oci arch:x86_64
$ image-builder manifest distro:rhel-10.0 type:oci arch:x86_64
While that makes typing out a manifest or build command by hand a tiny bit more tedious, it also makes it nice that the args aren't positional anymore and opens up the way to make distro optional too.
So you could do:
$ image-builder manifest type:qcow2
which would imply distro:$hostdistro
,arch:$hostarch
, and blueprint:/dev/null
(empty).
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.
While that makes typing out a manifest or build command by hand a tiny bit more tedious, it also makes it nice that the args aren't positional anymore and opens up the way to make distro optional too.
One issue with this is that we're inventing a new convention for non-positional arguments with option:value
instead of the standard --option=value
...
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.
[..]
Or we could drop this property (copy/pastable).
It's a nice property but yes I don't think it's important enough to make the output of another command so unusual.
[..]
Let's do that then, it's the most simple and straightforward change. I am a little bit sad about it because now:
$ image-builder manifest distro:rhel-10.0 type:oci arch:x86_64
error: cannot find blueprint "arch:x86_64"
$ image-builder build distro:rhel-10.0 type:oci arch:x86_64
error: cannot find blueprint "arch:x86_64"
We could change the default for image-builder-cli list-image
to only show same arch images by default and hint at something like "--all" to see all, then we would have preserved the copy/paste property again (at least by default) and it's nicer for the "build" case. Open for ideas of course but that seems a reasonable path forward(?).
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.
I pushed this tweak now in a "fixup!" commit for easier review and squash them all at the end:
$ image-builder manifest centos-9 qcow2
...
$ image-builder manifest centos-9 qcow2 ./path/to/blueprint
...
image-builder manifest --arch s390x centos-9 qcow2 /path/to/blueprint
...
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.
Would it be nicer if the architecture was a flag option (
--arch
)? That way we could make blueprint an optional positional argument, which I think would be a more common usage. Switching the arch would probably be less common.
I'd agree that this would be the more common usage but for the build command, not the manifest. My reasoning is that we will most probably end up generating manifests on a host that may not have the desired architecture. For "internal" usage, I'd be fine with BP being the an option instead.
There's no perfect solution here, as I can make an argument for any combination of BP and arch (not) being a positional argument.
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.
Fwiw, I have no strong opinion, I like the copy/paste property of the original design and "bib" also rquires an argument (currently) to pass a blueprint. Going back to the previous way is as easy as removing the last commit :) But I'm more interested in a way forward right now than which way it is :) (I would love to get this in before EOY)
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.
This had some more (offline) discussion with Ondrej and Achilleas and the latest agreement is:
This commit tweaks the argument handling based on the suggestion
by Achilleas and Ondrej (thanks!). Now it takes
$ image-builder manifest qcow2 ./path/to/blueprint
...
$ image-builder manifest --arch s390x --distro centos-9 qcow2
...
If no arch is specified the hostname arch is used. If no distro
is specified in either the blueprint or the commandline it is
auto-detected based on the host.
Note that if the distro from the comandline and the blueprint
diverge an error is raised. We can relax this rule and just
add precedence, e.g. commandline always overrides the blueprint
but ideally we would have a clear use-case here so we start
conservative and can always relax this rule later (the inverse
is much harder).
This means it is no longer copy/paste friendly from `list-images`
by default but instead we can provide a new
`list-images --output=shell` option that outputs in exactly the
format that `image-builder [manifest|build]` need.
df44603
to
82e057f
Compare
d4101ef
to
d46d430
Compare
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.
Nice work. I've added a few comments.
HACKING.md
Outdated
The go source code of image-builder-cli is under | ||
`./cmd/image-builder`. It uses the | ||
[images](https://github.com/osbuild/images) library internally to | ||
generate the imagess. Unit tests (and integration tests where it makes |
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.
typo: imagess
// PipelineNamesFrom will return all pipeline names from an osbuild | ||
// json manifest. It will error on missing pipelines. | ||
// | ||
// XXX: move to images:pkg/manifesttest? or something |
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.
IMO yes.
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.
I added this as a TODO
depsolvedSets[name] = res.Packages | ||
repoSets[name] = res.Repos |
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.
It may be good to note here that the code discards the SBOM part of res
.
cmd/image-builder/main.go
Outdated
@@ -69,6 +104,17 @@ operating sytsems like centos and RHEL with easy customizations support.`, | |||
listImagesCmd.Flags().String("output", "", "Output in a specific format (text, json)") | |||
rootCmd.AddCommand(listImagesCmd) | |||
|
|||
manifestCmd := &cobra.Command{ | |||
Use: "manifest <distro> <image-type> [<arch>]", |
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.
Would it be nicer if the architecture was a flag option (
--arch
)? That way we could make blueprint an optional positional argument, which I think would be a more common usage. Switching the arch would probably be less common.
I'd agree that this would be the more common usage but for the build command, not the manifest. My reasoning is that we will most probably end up generating manifests on a host that may not have the desired architecture. For "internal" usage, I'd be fine with BP being the an option instead.
There's no perfect solution here, as I can make an argument for any combination of BP and arch (not) being a positional argument.
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.
Looks great. I would like to have an answer for the seeding, other comments are nitpicks. :)
cmd/image-builder/filters.go
Outdated
if err != nil { | ||
return nil, err | ||
} | ||
// strip prefixes to make ib copy/paste friendly when pastring output |
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.
pastring -> pasting
internal/manifestgen/manifestgen.go
Outdated
for name, pkgSet := range packageSets { | ||
res, err := solver.Depsolve(pkgSet, sbom.StandardTypeNone) | ||
if err != nil { | ||
return nil, nil, err |
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.
Not sure how much this is worth since we really need a shared helper, but still: I think this error should be wrapper with name
.
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.
Good point, I wrapped all errors from the default*Resolver now
internal/manifestgen/manifestgen.go
Outdated
if err != nil { | ||
return err | ||
} | ||
preManifest, warnings, err := imgType.Manifest(bp, *imgOpts, repos, 0) |
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.
What about the seed here? I think the we should make it random by default. A fixed seed should be opt-in.
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.
Thanks, (very) nice catch and urg for missing this.
Thinking a bit about it I wonder^Wthink we should look into images and tweak the API here, it seems in almost all "real" use-cases one would want a non-zero seed here so maybe this could become either a pointer (and on nil we just pick a random seed) or keep as is but assign a random value if we get "0" in images. Obviously followup material and I fixed this instance of the issue here but thinking about the future/a followup, wdyt?
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.
I opened osbuild/images#1107 as an RFC
This commit adds a helper to find exactly a single image from a given disto/type/arch description. This will be used in `manifest`, `build` and potentially more. It is meant to support copy/paste from the `image-builder list-images` output, so: "distro:centos-9" is support just like "centos-9" (same for distro/imgType/arch).
This commit adds a basic HACKING.md that explains the bare mimimum to get started, including `go test -short` to skip the expensive tests. Contains also a drive-by rename of the test dependency install for the GH action.
This commit adds a new `manifesttest` that helps sharing code when testing generated osbuild manifests.
This commit adds a new generic `manifestgen` package that can be used to generate osbuild manifests. It works on a higher level then the low-level `manifest` package from `images` and provides plugable resolvers and a streamlined API. This package is meant to be moved to the `images` library eventually.
This commit implements the `manifest` command for `image-builder`. It will generate an osbuild manifest based on the given inputs, e.g.: ``` $ ./image-builder manifest centos-9 qcow2 {"version":"2","pipelines":[{"name":"build","runner":",... ``` Note that there is an integration test but because of the depsolve it will be slow. It will be skipped when doing `go test -short`.
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.
I like this very much. Some minor issues inline.
cmd/image-builder/main.go
Outdated
Short: "Build manifest for the given distro/image-type, e.g. centos-9 qcow2", | ||
RunE: cmdManifest, | ||
SilenceUsage: true, | ||
Args: cobra.MinimumNArgs(2), | ||
Args: cobra.MinimumNArgs(1), |
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.
Doesn't cobra
have RangeArgs(1, 2)
?
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.
Nice, TIL!
This commit provides a `blueprintload` package that can be used to load blueprints from json/toml from a path. This will be used in `bootc-image-builder` and `image-builder-cli` and should eventually be merged into `images`.
This commit adds support to pass a blueprint to the manifest generation.
This commit adds an integration test for the container resolving when generating a manifest. This is sadly quite indirect right now because `manifestgen` needs some more support from `images` and the `distro_test` code there (that will hopefully come soon(ish)).
This commit tweaks the argument handling based on the suggestion by Achilleas and Ondrej (thanks!). Now it takes ```console $ image-builder manifest qcow2 ./path/to/blueprint ... $ image-builder manifest --arch s390x --distro centos-9 qcow2 ... ``` If no arch is specified the hostname arch is used. If no distro is specified in either the blueprint or the commandline it is auto-detected based on the host. Note that if the distro from the comandline and the blueprint diverge an error is raised. We can relax this rule and just add precedence, e.g. commandline always overrides the blueprint but ideally we would have a clear use-case here so we start conservative and can always relax this rule later (the inverse is much harder). This means it is no longer copy/paste friendly from `list-images` by default but instead we can provide a new `list-images --output=shell` option that outputs in exactly the format that `image-builder [manifest|build]` need.
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.
Looks good from my PoV
This commit implements the
manifest
command forimage-builder
.It will generate an osbuild manifest based on the given inputs,
e.g.:
Note that there is an integration test but because of the depsolve
it will be slow. It will be skipped when doing
go test -short
.Integration tests for ostree commit, this is because ostree commit integration tests will need "build" first because the way this is tested today is that first an edge-commit is created, then an edge-ami based on this commit is generated. But "build" is currently missing
Note that this has no README.md update for
manifest
because manifest is considered an internal command, once "build" is added (which is easy once manifest is there) "build" will be documented.