Skip to content
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

arriving at a stable, functional, and sensical recipe standard #180

Open
xynydev opened this issue May 11, 2024 · 26 comments
Open

arriving at a stable, functional, and sensical recipe standard #180

xynydev opened this issue May 11, 2024 · 26 comments
Assignees
Labels
breaking Introduces a breaking change. type: discussion Questions, proposals and info that requires discussion.
Milestone

Comments

@xynydev
Copy link
Member

xynydev commented May 11, 2024

(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:

base-image:
    url: ghcr.io/ublue-os/silverblue-main
    tag: 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` 
result-image:
    name: weird-os
    description: This is my personal OS image.
    tags: # replaces the "latest" and timestamp tags
       - gts
stages:
    ...
modules:
    ...

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

@xynydev xynydev added type: discussion Questions, proposals and info that requires discussion. breaking Introduces a breaking change. labels May 11, 2024
@xynydev xynydev mentioned this issue May 11, 2024
8 tasks
@fiftydinar
Copy link
Contributor

fiftydinar commented May 11, 2024

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.

@xynydev
Copy link
Member Author

xynydev commented May 11, 2024

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.

@gmpinder
Copy link
Member

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.

@gmpinder
Copy link
Member

Something else that could probably be added later for the user's image is labels: which would just be a map

@gmpinder
Copy link
Member

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.

@gmpinder
Copy link
Member

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.

@gmpinder
Copy link
Member

gmpinder commented May 12, 2024

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.

@xynydev
Copy link
Member Author

xynydev commented May 12, 2024

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.

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.

@xynydev
Copy link
Member Author

xynydev commented May 12, 2024

I do think that result-image: could be something else like final-image or main-image.

Maybe final-image then, definetly not main-image, that's an overloaded term. metadata would be another possible key name for it.

@gmpinder
Copy link
Member

Maybe final-image then, definetly not main-image, that's an overloaded term. metadata would be another possible key name for it.

I like metadata. Feels k8s-ish

@fiftydinar
Copy link
Contributor

final-image is better imo, metadata can be referred to almost anything that contains information.

@xynydev
Copy link
Member Author

xynydev commented May 12, 2024

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.

@CarrotManMatt
Copy link

Could you do a combination? final-image-metadata or is that a bit waffly?

@xynydev
Copy link
Member Author

xynydev commented May 13, 2024

That is a bit "waffly" IMO yeah 😅

@gmpinder
Copy link
Member

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

@xynydev
Copy link
Member Author

xynydev commented May 18, 2024

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.

@gmpinder
Copy link
Member

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.

@xynydev
Copy link
Member Author

xynydev commented May 18, 2024

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:
  ...

@gmpinder
Copy link
Member

I'm liking that

@gmpinder gmpinder self-assigned this Jun 30, 2024
@gmpinder gmpinder added this to the v0.10.0 milestone Jun 30, 2024
@gmpinder
Copy link
Member

gmpinder commented Jul 1, 2024

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).

@xynydev
Copy link
Member Author

xynydev commented Jul 1, 2024

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.

@gmpinder
Copy link
Member

gmpinder commented Jul 1, 2024

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.

@xynydev
Copy link
Member Author

xynydev commented Jul 1, 2024

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?

@gmpinder
Copy link
Member

gmpinder commented Jul 1, 2024

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.

@xynydev
Copy link
Member Author

xynydev commented Jul 2, 2024

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.

@gmpinder
Copy link
Member

gmpinder commented Jul 2, 2024

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.

I can agree to this. This will require some research outside of this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking Introduces a breaking change. type: discussion Questions, proposals and info that requires discussion.
Projects
None yet
Development

No branches or pull requests

4 participants