#version check impl details
1 messages ยท Page 1 of 1 (latest)
bleh
so, the index annotations not supported error is technically true ๐ฆ
the right call here i think is to try to attach to the manifest if we have only one platform, and to the index if we have multiple? does that work?
ideally there would be a way to do this in buildkit (i'll add this to my long list of things to maybe in bk)
The thing I don't quite grasp is that we DO have multiple platforms on our image, don't we?
So, I updated https://github.com/dagger/dagger/pull/8396 to retrieve the latest version from the annotations
It will try to grab the annotations from wherever works
Not sure about Container.WithManifestAnnotation, I think WithAnnotation should be good? i really don't love that there are so many places to attach annotations in oci
but yes, there is a chicken-and-egg problem
๐ข no real way around it
related issue https://github.com/dagger/dagger/issues/6999\
What are you trying to do? I wan't to make the exported tar for ctr i import, but now I could't added any custom annotation into index.json, which is important for https://github.com/contai...
neat ๐
mm, but only for publish - for just container, we don't
@nova osprey For the actual annotation part ...
basically what I'm doing is changing Container.Publish here:
https://github.com/dagger/dagger/blob/main/core/container.go#L1082
Currently doing a:
key := exptypes.AnnotationManifestDescriptorKey(&platformSpec, annotation.Key)
opts[key] = annotation.Value
(for each variant)
ugh, the annotation api is a totalmess (i made it, such regret)
If I try to use exptypes.AnnotationIndexKey() or AnnotationIndexDescriptorKey I get:
Error: response from query: input: failed to export: index annotations not supported for single platform export
yeah, so you should be able to have a check for len(platformVariants) - the published images would then have it set at the top-level on the index, and the other case you can do what you're currently doing
let me clean this up and open a separate PR, will make life easier
technically this check is bad, it should also include manifest descriptors probably
but bleh
@nova osprey btw, wasn't sure whether to add those in opts in there OR lower level in https://github.com/dagger/dagger/blob/cff0042946c68b9ef2c1128b4ed089097f443b33/engine/buildkit/containerimage.go?plain=1#L226 using AddMeta
The thing I don't quite understand is (and I'm trying this in our own engine publish pipeline): we DO have multiple platforms, so attaching to index should work yeah?
oh if this in pub lish, then i'm not sure
and related: is there any workaround? e.g. does this work if the API PR is merged first since we use main engine on CI (I think?), or no way around it until we actually publish a new version
everyone who works on the engine needs to grab a dev build then
not impossible, but generally a bit annoying
could this be a bug?
ah
not every image we publish is multi-platform
for example, the gpu variant is only published for linux/amd64
I think that could be causing it
oh ok
let me try with the check
@nova osprey oh btw -- I should be using the Descriptor variant of the exptypes right?
e.g. AnnotationIndexDescriptorKey and AnnotationManifestDescriptorKey ?
i don't think so, we want to attach at the top-level of the manifest/index
@nova osprey uhm ... another thing: if there ARE multiple platforms, don't we have the risk of them having different annotations?
Since Publish takes []Containers for variants?
oh you're not wrong
Alternatively instead of Container.WithAnnotation it would be Publish taking a list of annotations
sorry i'd forgotten that
mm
i think we don't want to move more stuff into Publish - e.g. we don't want to exacerbate the problem with needing a bunch of extra stuff you can't pass around modules
but yeah this is tricky
I don't quite understand the difference between the two ๐
I initially tried the Descriptor-less variant and I couldn't quite catch the annotations back when querying the registry -- I probably need to get it from somewhere else in the response
Basically there's 2 solutions then:
- Keep it per-manifest
- Do some deduping in Publish -- whichever annotations are the same for all containers, move to the index. Keep the rest per-manifest. But I think it's a bit too magic?
(err -- basically, keep WithAnnotation and then go with 1 or 2)
so.
- index puts it on the top-level of the index, at the annotations at the the top-most level
- manifest descriptor puts it in the index, in the descriptor, right next to the annotations for each manifest
- manifest puts it in the top-level of the manifest, which is in the manifest, so we need another level of traversal
index-descriptor is an insane edge case, since it can't actually be pushed to the registry
we can put it in manifest-descriptor, and the manifest actually
that way, it's in the index, and gets caught for multi-platform
and it's in the manifest, for single-platform
i don't think so, we want to attach at the top-level of the manifest/index
manifest descriptor puts it in the index, in the descriptor, right next to the annotations for each manifest
So we DO want it in the manifest descriptor, right?
(e.g. that's the top-level?)
yeah, i think that works
i think doing both is probably the least painful for implementation, and is probably not too unexpected for users
then we don't need the conditional about number of platforms we were talking about
๐ exactly
and this?
i think WithAnnotation is good - manifest/manifest descriptor combo is probably what users want 9/10 times
if there's demand to have it on the index, we can add it as an option in the future
@nova osprey UGH ... this is never ending
Is there a chance our registry in the unit test suite doesn't support annotations?
I'm not getting any annotations back
Tried to push instead manually to aluzzardi/test:v0.12.0 (on docker hub) and I can grab the annotations back using the same code of the unit test
oh no
uh that's wild
that would be weird, i don't think any registries should be doing that
is this TestManifestAnnotations?
a modified version of that, but yeah
I pushed to the hub and then tried this:
package main
import (
"fmt"
"net/http"
"os"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
)
func main() {
testRef := "aluzzardi/test:v0.12.0"
parsedRef, err := name.ParseReference(testRef, name.Insecure)
if err != nil {
panic(err)
}
imgDesc, err := remote.Get(parsedRef, remote.WithTransport(http.DefaultTransport))
if err != nil {
panic(err)
}
img, err := imgDesc.Image()
if err != nil {
panic(err)
}
manifest, err := img.Manifest()
if err != nil {
panic(err)
}
fmt.Fprintf(os.Stderr, "%+v\n", manifest.Annotations)
}
for which I get:
map[org.opencontainers.image.version:v0.1.2]
the same print in the unit test gives me map[] ๐ฆ
hm, if for the test you set org.opencontainers.image.version does it work?
instead of io.dagger.foo
maybe something might be filtering the annotation away?
Nah, but I'll try anyway
I was using io.dagger.version before and it worked (on the hub, not unit test)
recently switched to org.opencontainers.image.version
@nova osprey same same ๐ฆ
what
hmm, we could try subbing in a different registry to the test? but also, we use these in buildkit upstream, never seen anything like this
@nova osprey uh, got it
I was pushing using engine publish which is multi platform, my test is single platform
and for some reason this doesn't work for single platform :?
For multi here's the index, with manifests containing annotations:
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:dee65e4471e8aff605f19f1af69e78f16838f040eaf84cde4aa3ad4328270772",
"size": 5908,
"annotations": {
"org.opencontainers.image.version": "v0.1.2"
},
"platform": {
"architecture": "amd64",
"os": "linux"
}
}
single however lacks the annotations:
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"digest": "sha256:f9ffcc1aa1e4871f64c47a55bab18e66fe245cbf0b99caff945b1078eec5673e",
"size": 8755
},
"layers": [
what's on the manifest? i would of thought that it would be here ๐ข https://github.com/dagger/dagger/pull/8409/files#diff-10d41febe6f07f3eed32775ac5ec0a09eeda9867db7f5f3c57a39c75b90b708aR1131-R1135
Descriptor adds it here
non-descriptor case should add it in here
it doesn't though ... maybe I shouldn't be using both?
trying
for _, annotation := range annotations {
if len(platformVariants) == 0 {
opts[exptypes.AnnotationManifestKey(&platformSpec, annotation.Key)] = annotation.Value
} else {
opts[exptypes.AnnotationManifestDescriptorKey(&platformSpec, annotation.Key)] = annotation.Value
}
}
same
fmt.Printf("%s\n", imgDesc.Manifest)
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"digest": "sha256:62fffa44596631db76264bd72e75cf255484e7516c50b7c9ad39dc022d20dc7f",
"size": 430
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:690e87867337b8441990047e169b892933e9006bdbcbed52ab7a356945477a4d",
"size": 4086934
}
]
}
(in the unit test)
okay, i'm not entirely sure why that is.
it should be there. i would probably add some prints/etc in the buildkit code and inspect why it's not doing that
i can dive a bit more in tomorrow, but working on cutting the v0.13.0 release rn
๐
@nova osprey Oh, last thing:
Do you happen to know the difference between passing the annotations directly to in exporter.Resolve (e.g. expInstance, err := exporter.Resolve(ctx, 0, opts)) vs calling AddMeta?
i think they should end up in the same place
but they get propagated from different places
can't quite remember off the top of my head
Same result with AddMeta ... help appreciated tomorrow ๐
@nova osprey @hot phoenix some findings:
so, I created an image with this command:
docker buildx build . --output "type=image,name=ttl.sh/marcos:6,annotation.foo=bar,push=true"
Which AFAIK it's very similar to what we do in Dagger. As we call the image exporter with the publish flag in true when we publsih an image.
this is the resulting buildkit index manifest:
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:ae055e0221b421f486348a2e1cf8d2f7a38af8549be06a2ee71234cb877152e6",
"size": 521,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:6028d49116f2227b58d6cb653cd9055d0b98ddb11069db8e90b3764e53eeed38",
"size": 565,
"annotations": {
"vnd.docker.reference.digest": "sha256:ae055e0221b421f486348a2e1cf8d2f7a38af8549be06a2ee71234cb877152e6",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
}
]
^ there's two things to note here:
- The
annotationis not there. - The index contains two manifest. One for the actual container image with the proper
platformobject, and a second one with anattestationmanifest with anunknownplatform
Now, if I call the command like this (note the annotation-index change):
docker buildx build . --output "type=image,name=ttl.sh/marcos:7,annotation-index.foo=bar,push=true"
here's the resulting manifest:
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:465f515dfba9a241c3af16b4154e4161db1e8de1055b753434874158e7ae05d9",
"size": 480,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:36ab7585dd7e22bb809d4f915632b4be02b8857c49e8bce9e457b0f76af8a83d",
"size": 565,
"annotations": {
"vnd.docker.reference.digest": "sha256:465f515dfba9a241c3af16b4154e4161db1e8de1055b753434874158e7ae05d9",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
}
],
"annotations": {
"foo": "bar"
}
^ you can see the annotations object in the image index
I haven't dug deeper but my theory at this stage is that the previous error "single platform" error that we were getting before is because as we're calling the exporter manually, we're probably not passing the attestation manifest as buildctl is currently doing and that's why the exporter is complaining
this is because the annotation should be getting set on the manifest - if you inspect the contents of the manifest, the annotation should be there
this is the difference between manifest and manifest-descriptor - manifest descriptor sets it on the index, in the descriptor for that manifest
@nova osprey if you have spare time to look into this let me know. I'm stuck :/
gimme 5, currently writing up some investigation into mark's issue
What about the platform theory? Could that be what's happening?
the annotations shouldn't be added to the attestation manifest (which is the one with unknown/unknown)
digging in properly now
think i've found it, testing my theory now
@hot phoenix am I good to force push? I've rebased as well.
Yep!
pushed
the annotations api is horrid, looks like we need nil platforms ๐
also added tests for single vs multi platform cases
my theory was more about that index annotations are working with builct because we have the attestation manifests that we're not including when we call the Exporter from Dagger
and I thought that that was the reason we were getting that "single platform" error
https://github.com/dagger/dagger/pull/8396 this lgtm to me now, just left a little nit