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

Add annotations support to output #2879

Merged
merged 6 commits into from
Jun 17, 2022
Merged

Conversation

jedevc
Copy link
Member

@jedevc jedevc commented May 25, 2022

Fixes #1220

This PR introduces support for creating and attaching annotations to the exporter. These annotations can be specified via frontends, or via the exporter output parameters (with the latter overriding the former).

For now, this is just the containerimage exporter, but we should probably add it to the other exporters as well, at the very least the oci exporter 👀

@jedevc jedevc requested a review from tonistiigi May 25, 2022 15:30
@tonistiigi
Copy link
Member

For now, this is just the containerimage exporter, but we should probably add it to the other exporters as well, at the very least the oci exporter

Yes, we should remove the duplication in here. The imagewriter part is already shared among these exporters but we should also do a shared method for parsing the image-specific attr options and putting them to struct that can be passed to the imagewriter. Maybe we can do this on a separate PR already and then make this PR use it.

I still think we need separation between annnotations, descriptor annotations, and OCI root index annotation. For example signature annotations would need to be on descriptors.

Other than that you can also start working on the test coverage.

@jedevc
Copy link
Member Author

jedevc commented Jun 7, 2022

Think this is getting closer now, need to start working on some test coverage, but think the shape of the code is about right.

I still think we need separation between annnotations, descriptor annotations, and OCI root index annotation.

Regarding annotations to OCI root indexes, personally I think we might want to explicitly not support this scenario - as mentioned in in #1220, it's fairly rare to see annotations attached like this. Additionally, if more than one platform is not supplied to buildkit, an image index isn't generated - this means that whether that annotation actually gets used is a matter of what platforms are built, which seems like a confusing user experience.

I think if we support annotation.<x> and annotation-descriptor.<x> we should be good for most use cases - we could always come back and add support for the OCI root indexes (using something like annotation-index.<x>) later down the road if it becomes apparent that such a use case is necessary.

Alternatively, is there any reason we couldn't switch to always producing indexes, even when there's only a single platform? If we're interested in signing entire indexes, then this would probably be a precursor to being able to do that.

we can just let user define all annotations with unique key. -o annotation.<key>=value

Do we want to support setting arch-specific annotations for opts specified at the command line, or just allow that for frontends? If so, what would the option look like? I was thinking something like annotation-<arch>.<key>=<value>, but then we'd probably want to update the internal frontend ref.annotation syntax to match. Although that might clash with doing annotation-descriptor.

@jedevc jedevc force-pushed the annotations-support branch 2 times, most recently from 2d2be6d to 3d9bcf4 Compare June 8, 2022 12:49
@jedevc
Copy link
Member Author

jedevc commented Jun 8, 2022

I've gone and added a test for the OCI and ContainerImage annotations, which tests annotations set from both the frontend and from options. It's quite a long test, so let me know if it needs to be split up a bit more, or if it should be in a different part of the codebase.

R.e. the two points above - I've implemented annotations on the image index (with the noted caveats), and only allowed annotations to the image manifests when using options.

@jedevc jedevc force-pushed the annotations-support branch 2 times, most recently from 7419aea to bca7d4f Compare June 10, 2022 15:40
@jedevc jedevc marked this pull request as ready for review June 10, 2022 15:42
exporter/containerimage/common.go Outdated Show resolved Hide resolved
exporter/containerimage/common.go Outdated Show resolved Hide resolved
exporter/containerimage/common.go Outdated Show resolved Hide resolved
exporter/containerimage/common.go Outdated Show resolved Hide resolved
exporter/containerimage/export.go Show resolved Hide resolved
exporter/containerimage/exptypes/types.go Outdated Show resolved Hide resolved
exporter/containerimage/exptypes/types.go Outdated Show resolved Hide resolved
exporter/containerimage/exptypes/types.go Outdated Show resolved Hide resolved
exporter/annotations.go Outdated Show resolved Hide resolved
exporter/annotations.go Outdated Show resolved Hide resolved
@jedevc
Copy link
Member Author

jedevc commented Jun 14, 2022

Have hopefully addressed the comments - except for the one about updating docs, will try and get to that one in a little bit.
Otherwise, should be ready for another review.

@johnsonshi
Copy link

johnsonshi commented Jun 14, 2022

Hi @jedevc, pardon me as I am not quite familiar with the exporter code. You mentioned These annotations can be specified via frontends, or via the exporter output parameters (with the latter overriding the former).

Does that mean the work in this PR will be progress towards the following scenario?

With this PR on exporter code (+ I guess future PR on the frontend/client), can a cli user can specify custom annotations such as the following?

docker buildx build \
  --annotation 'org.opencontainers.image.authors=authorName' \
  --annotation 'org.opencontainers.image.licenses=Apache' \
  -f Dockerfile -t myimage:latest .

@jedevc
Copy link
Member Author

jedevc commented Jun 14, 2022

Yup this is progress towards that exact scenario - the final syntax of how this will look in buildx is still TBD, but probably quite similar to what you describe 🎉

exporter/containerimage/opts.go Outdated Show resolved Hide resolved
exporter/containerimage/writer.go Outdated Show resolved Hide resolved
exporter/containerimage/annotations.go Outdated Show resolved Hide resolved
exporter/containerimage/exptypes/types.go Outdated Show resolved Hide resolved
exporter/containerimage/exptypes/types.go Outdated Show resolved Hide resolved
exporter/containerimage/annotations.go Show resolved Hide resolved
return exporterAnnotationKey(AnnotationManifestDescriptor, p, key)
}

func exporterAnnotationKey(annotationType string, platform *ocispecs.Platform, key string) string {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could define a type for annotationType for extra safety. Keep private if nothing outside uses it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do this with type annotationType string but it doesn't add much extra safety since go will allow implicitly converting between string and annotationType (because it's an alias)
If we create a struct to do this and actually construct a new type, then switch-statements no longer work.

client/client_test.go Outdated Show resolved Hide resolved
@tonistiigi
Copy link
Member

Although this isn't an LLB feature, add a capability for it in https://github.com/moby/buildkit/blob/master/solver/pb/caps.go in case there is a need for a client to detect if this feature is supported.

README.md Show resolved Hide resolved
solver/pb/caps.go Outdated Show resolved Hide resolved
The OCI and ContainerImage exporters share a number of common options,
since the underlying format is very similar. Previously, the parsing and
storage of these options was duplicated across both packages.

This patch introduces a set of CommonOpts that can be shared between
both packages - these include the image name, compression levels, build
info and other oci-related options. Additionally the parsing code is
simplified, by introducing helpers to more easily read boolean options.

Signed-off-by: Justin Chadwell <me@jedevc.com>
jedevc and others added 5 commits June 16, 2022 13:25
This patch adds support for attaching annotations to the oci and
containerimage exporters.

Annotations can be created by frontends by attaching them to the result
metadata, or from the parameter keys passed to the exporter.

Annotations can be attached to 4 different levels:
- Image manifest (per platform)
- Image manifest descriptors in the image index (per platform)
- Image index
- Image index descriptors in the OCI image layout

Note that the only one the image manifest is always guaranteed to be
present (since an image index is not always created).

Signed-off-by: Justin Chadwell <me@jedevc.com>
Signed-off-by: Justin Chadwell <me@jedevc.com>
Allows clients to query if annotations exporting is supported.

Signed-off-by: Justin Chadwell <me@jedevc.com>
Signed-off-by: Justin Chadwell <me@jedevc.com>
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
@tonistiigi tonistiigi merged commit a6a114a into moby:master Jun 17, 2022
@JcJinChen
Copy link

Yup this is progress towards that exact scenario - the final syntax of how this will look in buildx is still TBD, but probably quite similar to what you describe 🎉

It looks cool. I wonder when this feature will be available, such as add "annotation" flag. Thanks. I test the code from master branch. This looks like a failure.

@jedevc
Copy link
Member Author

jedevc commented Jul 21, 2022

Heya @JcJinChen, the feature is currently available on buildkit master. However, the proposed syntax using the --annotation flag is not yet introduced - to track that, see docker/buildx#1171 - any comments or suggestions you might have would be really helpful. Because adding annotations using the docker builder so far hasn't been possible, we're not quite sure how users will use this, and how we should optimize for the default experience.

I've added some docs in #2975 to better explain how to use the feature as-is - if you're using buildx instead of buildctl directly you just need to add the annotation.* options to your --output flag on the buildx command line.

Hope that helps 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add annotations support to OCI outputter
4 participants