-
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
Add support for building images from ostree containers and the Fedora CoreOS qcow2 image type #243
Conversation
b8b990f
to
b19437c
Compare
617ce72
to
25ca0c0
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.
I'm very happy with this PR and I haven't found any issues. However, it's a big one, so I would love a third pair of eyes to take a look. @achilleas-k should we ask someone explicitly? Any ideas whom? :)
@@ -689,6 +707,7 @@ func newDistro(version int) distro.Distro { | |||
UEFIVendor: "fedora", | |||
}, | |||
iotQcow2ImgType, | |||
coreosQcow2ImgType, |
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 aarch64?
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 it at first but then realised I needed to get the base container in our CI registry to test it and decided to get this open so people can review and I can add it in a follow-up.
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 think I noticed an oversight, but would rather fix that in a follow-up than rebasing it tbh, this is plenty useful as it is.
- Take the code from https://github.com/achilleas-k/images/tree/bifrost-image/cmd/osbuild-deploy-container and merge it into this repository, using the code from osbuild/images#243 as a `replace` - Also merge in osbuildbootc
@@ -72,6 +77,9 @@ type ImageOptions struct { | |||
// Indicate if the 'org.osbuild.rhsm.consumer' secret should be added when pulling from the | |||
// remote. | |||
RHSM bool `json:"rhsm"` | |||
|
|||
// TLS verification for container sources. | |||
TLSVerify *bool `json:"tls-verify"` |
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.
since there are multiple things here that are "remote" artifacts it might be a little confusing to have this just apply to one of them and still name it TLSVerify
.
One thing we could do here is break out sets of options that go together into subordinate objects.
i.e.
type ContainerImageOptions struct {
Container string `json:"container"`
TLSVerify *bool `json:"tls-verify"`
}
...
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.
There's two things going on here that I don't like and I'm unsure of:
- The
ostree.ImageOptions
and more generally thedistro.ImageOptions
that exist separately from things like the blueprint customizations. These I want to merge into a build config. - The way that users will be specifying an ostree container for a build when this gets into osbuild-composer.
The way I added the options now sort of reflects things that might happen in composer, but that's just leftover internal structure from the split.
All that said, none of this is considered "stable API" (yet) in images, so I did the quickest thing that felt natural at the time. You're right though, a completely separate object is nicer. Getting the "build config" done soon would be even better.
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'm OK with whatever.
img.Compression = t.compression | ||
|
||
return img, nil | ||
} |
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.
There is a lot going on here. Maybe @achilleas-k we can get together and step through some of it.
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.
Sure, we can do that. For a high level description though: Almost all of this function is essentially creating the img
img := image.NewOSTreeContainerDiskImage(container, ref)
followed by setting options on the image based on image type settings and user customizations.
buildPipelines: []string{"build"}, | ||
payloadPipelines: []string{"ostree-deployment", "image", "qcow2"}, | ||
exports: []string{"qcow2"}, | ||
basePartitionTables: iotBasePartitionTables, |
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 probably need to dig into iotBasePartitionTables
a little bit more to understand why they are being used here.
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 based the image off the iot-raw-image and reused that partition table. I would say, instead of digging, point me to the default partition table you use in coreos images and I'll replicate it here.
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 is what I've been using for now.
There is one theme here, though, that I think we keep bumping up into, which is where definitions like this should live. I think it was also touched on in osbuild/bootc-image-builder#4
I
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.
For Image Builder (osbuild-composer and the service), the defaults are defined here. For all the RHEL images we build for example as part of the composes in Brew and for all the images in c.rh.c/ib, this is the source of truth right now.
@@ -340,7 +340,8 @@ func (p *OSTreeDeployment) serialize() osbuild.Pipeline { | |||
} | |||
} | |||
|
|||
if !hasRoot { | |||
if !hasRoot && p.ostreeSpec != nil { | |||
// NOTE: fails on container-based deployments |
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 either.. from my side this feels like something that would be done when composing the ostree commit or oscontainer rather than when composing an image. IOW I feel like this shouldn't be part of Image Builder at all?
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.
Locking the root password during deployment is something that's done for the official Fedora IoT image: https://pagure.io/fedora-kickstarts/blob/main/f/fedora-iot.ks#_9
We were replicating that here.
@@ -46,6 +46,10 @@ func TestImageType_PackageSetsChains(t *testing.T) { | |||
URL: "https://example.com", // required by some image types | |||
}, | |||
} | |||
if imageType.Name() == "coreos-qcow2" { | |||
options.OSTree.Container = "https://registry.example.com/image" |
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.
is this supposed to be a container pullspec? those don't often include https://
do they?
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 could be any string since the test doesn't really do anything with it, but you're right. Might as well make it look like a real spec.
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 helpful my review here is, I did a quick scan to get a feeling for the code and just added tiny coments/ideas inline. As a bit of a meta-comment, would it make sense to split something like ae57912 into it's own PR? It seems generally useful on its own and would make this PR smaller. But there are probably good reasons that I just don't know yet :) Hope this is still useful in some small way.
@@ -269,7 +269,8 @@ func (t *imageType) checkOptions(bp *blueprint.Blueprint, options distro.ImageOp | |||
} | |||
} | |||
|
|||
if t.name == "iot-raw-image" || t.name == "iot-qcow2-image" { | |||
if t.name == "iot-raw-image" || t.name == "iot-qcow2-image" || t.name == "coreos-qcow2" { |
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 wonder if if slices.Contains([]string{"iot-raw-image", "iot-qcow2-image", "coreos-qcow2"}, t.name) {
might be slightly nicer? It seems we are using this already. But size of the line is almost the same so maybe not a win.
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 think that's a good idea. This keeps growing and it'll be nicer to be able to append a single name to a list instead of needing to rewrite the comparison every time. Generally, we should have a nicer way to test these, but that's for another day.
Creates an org.osbuild.ostree.deploy.container stage. Validates the options with a regular expression that matches the schema. Takes a container as input. Validates the length of the input references to be exactly 1. See osbuild/osbuild#1402
The pipeline either way only supported one ostree commit, enforced when adding the resolved commits to the pipeline during serializeStart() and by checking the array length during serialize(). To simplify the requirement and avoid potential confusion when reading the struct itself, replace the array on the pipeline struct definition with a single commit spec (pointer) and keep the len == 1 check in the serializeStart() function that, by its interface, must accept an array. Also document the commit fields for OSTreeDeployment. These are private, so they wont show up in public API docs, but it's still useful to have them documented in the code.
Support a container source for OSTreeDeployment as an alternative to the ostree commit source. Currently, if a container is defined, it fails with an error. The commit source and the container source are now both pointers since they can be unset, but (will) we need to make sure at least one is set when serializing.
Move the ostree pull stage to be right before the ostree deploy stage. This should have no functional impact on the build and will make it easier to replace the two stages together. Old vs new stage order: org.osbuild.ostree.init-fs | org.osbuild.ostree.init-fs org.osbuild.ostree.pull | org.osbuild.ostree.os-init org.osbuild.ostree.os-init | org.osbuild.mkdir org.osbuild.mkdir | org.osbuild.ostree.pull org.osbuild.ostree.deploy | org.osbuild.ostree.deploy
When creating the ostree deployment pipeline, add the appropriate stages only when the ostree commit is specified. The stages are: org.osbuild.pull org.osbuild.ostree.deploy org.osbuild.ostree.remote org.osbuild.ostree.fillvar
Rename the NewOSTreeDeployment() constructor to NewOSTreeCommitDeployment() and add a second one called NewOSTreeContainerDeployment(). Each takes a different kind of source spec (ostree commit or container). The container constructor also requires the ref to be specified since it's not part of the container spec.
Add the org.osbuild.ostree.deploy.container stage when the content source for the deployment is a container.
Support both content source types on the OSTreeDiskImage ImageKind. A second constructor is defined, just like with the deployment pipeline of the image. The original constructor is renamed to NewOSTreeDiskImageFromCommit to differentiate and have a more informative name.
Only required properties should be specified through the constructor to make sure they are not accidentally left empty or nil. Optional properties are added via public fields of the pipeline object. Since the ignition platform is optional, change it to a public field. Also, to simplify the interaction between the two ignition properties, remove the boolean that signifies if ignition should be enabled and use the IgnitionPlatform string instead. Treat the empty string as the disabled value.
A new image functions called coreosImage() that requires a container source and creates a qcow2 image from a CoreOS ostree container. Based on the example manifest added in osbuild/osbuild#1402
Define the new image type using the new coreosImage() function and container deployment pipeline and add it to the x86_64 and aarc64 registries for Fedora.
We always aliased these types so that internal changes wouldn't always require changing our tooling interfaces but it's actually more annoying needing to change them every time something is added or changed in the internal types. These are development and testing tools. It's fine to use the internal types directly and keep them simple.
Use gpgkeys instead of concatenating multiple keys under gpgkey. The singular gpgkey was a leftover from an old format and now we use an array from the internal rpmmd.RepoConfig instead.
Modifying the root user fails when trying to modify a container deployment. Let's disable it for now until we figure out if it's possible.
Use the latest version from the Fedora 38 repo snapshots.
25ca0c0
to
d3e1734
Compare
Partially addressed comments (and rebased on |
Moved most of the commits to #272. I'll rebase this PR so that it only adds the coreos image once that's merged. |
@achilleas-k should be able to rebase now as #272 has landed \o/ |
Will rebase and fix conflicts then start addressing the remaining comments. |
This PR is stale because it has been open 30 days with no activity. Remove "Stale" label or comment or this will be closed in 7 days. |
This PR was closed because it has been stalled for 30+7 days with no activity. |
This PR adds support for the org.osbuild.ostree.deploy.container stage and a new image type that uses it called
coreos-qcow2
for Fedora.I tested the new image type locally with the container we added to the gitlab registry for testing the sample manifest in osbuild.
Some notes and open questions:
You can generate the manifest for this image with:
or build it directly with
You can also add a user to the config file which will create a user after the deployment before finalising the image: