Open xynydev opened 3 months ago
Generally looks good.
tags: # replaces the "latest" and timestamp tags
- gts
I'm interested in this part.
It would be possible to provide multiple tags, like gts
& latest
, right?
What about other images, like VanillaOS, which have different release schedules?
I guess that only latest
would be supplied short-term, while gts
is more of a Fedora/Universal Blue thing.
Maybe the equivalent for it would be lts
, but not sure. Just thinking around.
Yes, that's an already implemented feature, and can be used to set any set of custom tags on any image. latest
is added automatically if tags
isn't set, but after that, it's up to the user.
I think this structure makes way more sense TBH. I do think that result-image:
could be something else like final-image
or main-image
. The public key property is a good addition too. I was envisioning adding our own labels onto images that would be a link to the public key or something like that. This way we would be able to pull that information dynamically on build. But this property would be perfect for images that aren't built by bluebuild
.
Something else that could probably be added later for the user's image is labels:
which would just be a map
As for the "schema" for the recipe, the struct definitions and the use of serde already act like a schema enforcer. However, I think using schema's for the configuration of modules would be a really good idea to be able to validate the input before building.
So there is a jsonschema crate that we can use that is being actively maintained it would seem. Also we could include a tool to convert user's recipes using struct-convert. I used this at work for helping to create a helm values migration tool for deploying our services.
base-image: url: ghcr.io/ublue-os/silverblue-main
Just realized. I don't think this should be url:
. Image refs are their own separate spec from URL. Maybe name
, from
, image-name
, ref
. I just think URL is misleading a bit.
base-image: url: ghcr.io/ublue-os/silverblue-main
Just realized. I don't think this should be
url:
. Image refs are their own separate spec from URL. Maybename
,from
,image-name
,ref
. I just think URL is misleading a bit.
Yeah I was a bit iffy on that too, but don't know what would be better. from
isn't that clear either IMO. ref
could be? Will have to see how it's referred to in the spec.
I do think that result-image: could be something else like
final-image
ormain-image
.
Maybe final-image
then, definetly not main-image
, that's an overloaded term. metadata
would be another possible key name for it.
Maybe
final-image
then, definetly notmain-image
, that's an overloaded term.metadata
would be another possible key name for it.
I like metadata
. Feels k8s-ish
final-image
is better imo, metadata
can be referred to almost anything that contains information.
To spin that argument around: basically everything in the recipe concerns 'the final image', while metadata
would quite literally be the final images metadata, as in it's name, description, labels, etc.
That is a bit "waffly" IMO yeah 😅
So it's sounding like it's going to be something like this?
base-image:
ref: ghcr.io/ublue-os/silverblue-main:40
public-key: https://... # unimplemented, needed for base image verification, would be optional, and automatically supplied for ublue etc.
type: ostree # unimplemented, might be needed for effectively supporting different base images, which might need things like running `ostree container commit`
final-image:
name: weird-os
description: This is my personal OS image.
tags: # replaces the "latest" and timestamp tags
- gts
stages:
...
modules:
...
I think combining the tag
in with ref
makes things a little clearer especially since we aren't building FROM multiple tagged images
ref
is still unclear IMO, not sure what it could be instead, though. I think the reason I did it like this is to (1) possibly support matrixing with a single recipe in the future and (2) that the diffs when changing the version would look nicer.
But yeah, I probably agree that this is better.
How about something like:
base-image:
image: ghcr.io/ublue-os/silverblue-main:40
public-key: https://... # unimplemented, needed for base image verification, would be optional, and automatically supplied for ublue etc.
type: ostree # unimplemented, might be needed for effectively supporting different base images, which might need things like running `ostree container commit`
It feels a bit redundant, but it follows convention from k8s and docker compose. Maybe if we want, we can find another name for base-image
.
base:
image: ghcr.io/ublue-os/silverblue-main:40
public-key: https://... # unimplemented, needed for base image verification, would be optional, and automatically supplied for ublue etc.
type: ostree # unimplemented, might be needed for effectively supporting different base images, which might need things like running `ostree container commit`
metadata:
name: weird-os
description: ...
tags: [gts]
stages:
...
modules:
...
I'm liking that
Something that I think would be super useful. I've been looking through how the Bluefin Containerfile
is laid out and it gave me the idea of having something like:
base:
from-recipe: parent-recipe.yml
...
This could allow building tiered images like how bluefin and bluefin-dx are created.
FROM ${BASE_IMAGE}:${FEDORA_MAJOR_VERSION} AS base
# ...
FROM base AS dx
# ...
We could then build and push both in a single build process (once I figure that out).
That is similar to what I laid out as the other way to solve building multiple similar images alongside modules. Could be interesting. I don't see the practical difference from just building multiple images, one that uses the other as a base, except that GHA matrixes are concurrent so the build might be based on yesterdays image if the workflows aren't set up correctly.
I'm also not sure how your solution would interplay with GHA matrixing, so we'll see.
except that GHA matrixes are concurrent so the build might be based on yesterdays image if the workflows aren't set up correctly.
Yeah that was my main reasoning for it, though with having the full recipe we probably don't need to push both images. I think it would be a good idea for inheriting the base image and any stages that were defined in the parent recipe. We can try it out later and see what works best.
though with having the full recipe we probably don't need to push both images
Is there any point in this if both images aren't pushed?
Is there any point in this if both images aren't pushed?
Yeah, the whole system of inheriting from a recipe. Say you have a tiered set of images. One that we'll call basic
, and another we'll call deluxe
. The deluxe
recipe will be based off of the basic
recipe. If we then decide to change the basic
recipe to a new version of the image or a different base image altogether, the deluxe
recipe will also have this new base image. Any and all modules that are run for the basic
recipe will also be there for the deluxe
recipe without having to explicitly do a from-file
for each of the stages and modules that the deluxe
recipe should also have.
All in all it would just make it easier to keep certain images in sync with each other and prevent the issue of basing it off of yesterday's build of basic
.
If basic
is not published, that is essentially the same as doing from-file
from a file that contains multiple module definitions (AFAIK totally supported, as should be doing the same thing for stages). That basically just leaves the base-image
and related properties to be inherited from the basic
image. That feels like a really small improvement to basically re-implement a feature that already exists.
If there's some elegant solution that would push both basic
and deluxe
, I would 100% be for that. If not, this feels like a duplicate feature.
If there's some elegant solution that would push both
basic
anddeluxe
, I would 100% be for that. If not, this feels like a duplicate feature.
I can agree to this. This will require some research outside of this issue.
(this issue is filed under CLI, because this is the only place changes would have to be made to implement changes to the recipe format)
I had an epiphany. But let me preface a bit; if the purpose of the recipe is to be a versatile standard that describes the build and publish process of a native container image, is it as good as that as can be? And if not, aren't we in the broad ideal moment of time to evolve it?
Here's how it could look:
That's a sketch, but IMO it's already better than what we have now. Ideas and discussion appreciated here, though.
Multiple versions of the recipe standard could be supported in a way similar to other projects, say,
docker-compose.yml
do. I'd opt for using the$schema:
key to specify the version; that would force us to supply jsonschema for all supported versions, and the user to update both the autocomplete source and the actual version in their recipes at the same time. This would set a solid foundation for breaking recipe changes in the future. If rust can do jsonchema validation, maybe we could even get multi-version support in CLI with not much extra effort? #173@blue-build/members