What happened in your environment?
We use OCI images to package eBPF programs in Inspektor Gadget. We have an ig image export command that creates an oci layout file with the image. I wanted to use oras cp to copy the image to a remote registry, however it fails with:
$ oras cp --from-oci-layout ./mygadget.tar.folder:ghcr.io/inspektor-gadget/gadget/mygadget:latest localhost:5000/foo:latest --debug
Error: invalid argument "./mygadget.tar.folder:ghcr.io/inspektor-gadget/gadget/mygadget:latest": failed to find path "./mygadget.tar.folder:ghcr.io/inspektor-gadget/gadget/mygadget": stat ./mygadget.tar.folder:ghcr.io/inspektor-gadget/gadget/mygadget: no such file or directory
The issue seems to be related to the fact that the org.opencontainers.image.ref.name annotation is set to ghcr.io/inspektor-gadget/gadget/mygadget:latest in index.json:
mygadget.tar.folder/index.json:
{
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:69fb10d45f448525a39bb26ae2af71e57fe2b7aa774547eb57da38ddf08b12e0",
"size": 1278,
"annotations": {
"org.opencontainers.image.created": "2024-09-19T13:06:53-05:00",
"org.opencontainers.image.description": "TODO: Fill the gadget description",
"org.opencontainers.image.documentation": "TODO: Fill the gadget documentation URL",
"org.opencontainers.image.source": "TODO: Fill the gadget source code URL",
"org.opencontainers.image.title": "TODO: Fill the gadget name",
"org.opencontainers.image.url": "TODO: Fill the gadget homepage URL"
},
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.index.v1+json",
"digest": "sha256:f31a444623261efcc68601704dd3d980692a73a55f5031c8ddca58cc8a23876e",
"size": 1816,
"annotations": {
"org.opencontainers.image.created": "2024-09-19T13:06:53-05:00",
"org.opencontainers.image.description": "TODO: Fill the gadget description",
"org.opencontainers.image.documentation": "TODO: Fill the gadget documentation URL",
"org.opencontainers.image.ref.name": "ghcr.io/inspektor-gadget/gadget/mygadget:latest",
"org.opencontainers.image.source": "TODO: Fill the gadget source code URL",
"org.opencontainers.image.title": "TODO: Fill the gadget name",
"org.opencontainers.image.url": "TODO: Fill the gadget homepage URL"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:f99e163810194bd7fc50e23c9f1d7d827e464aac1766892f3747b1764301c3ae",
"size": 1278,
"annotations": {
"org.opencontainers.image.created": "2024-09-19T13:06:53-05:00",
"org.opencontainers.image.description": "TODO: Fill the gadget description",
"org.opencontainers.image.documentation": "TODO: Fill the gadget documentation URL",
"org.opencontainers.image.source": "TODO: Fill the gadget source code URL",
"org.opencontainers.image.title": "TODO: Fill the gadget name",
"org.opencontainers.image.url": "TODO: Fill the gadget homepage URL"
},
"platform": {
"architecture": "amd64",
"os": "linux"
}
}
]
}
According to https://github.com/opencontainers/image-spec/blob/v1.1.0-rc5/annotations.md, ghcr.io/inspektor-gadget/gadget/mygadget:latest is a valid value for the annotation.
Possible Fix
The following diff fixes the issue:
diff --git a/cmd/oras/internal/option/target.go b/cmd/oras/internal/option/target.go
index 489eeb8..33b83af 100644
--- a/cmd/oras/internal/option/target.go
+++ b/cmd/oras/internal/option/target.go
@@ -38,7 +38,6 @@ import (
"oras.land/oras-go/v2/registry/remote/auth"
"oras.land/oras-go/v2/registry/remote/errcode"
oerrors "oras.land/oras/cmd/oras/internal/errors"
- "oras.land/oras/cmd/oras/internal/fileref"
)
const (
@@ -120,6 +119,20 @@ func (opts *Target) Parse(cmd *cobra.Command) error {
}
}
+// Parse parses file reference on unix.
+func parseModified(reference string, defaultMetadata string) (filePath, metadata string, err error) {
+ i := strings.Index(reference, ":")
+ if i < 0 {
+ filePath, metadata = reference, defaultMetadata
+ } else {
+ filePath, metadata = reference[:i], reference[i+1:]
+ }
+ if filePath == "" {
+ return "", "", fmt.Errorf("found empty file path in %q", reference)
+ }
+ return filePath, metadata, nil
+}
+
// parseOCILayoutReference parses the raw in format of <path>[:<tag>|@<digest>]
func (opts *Target) parseOCILayoutReference() error {
raw := opts.RawReference
@@ -132,7 +145,7 @@ func (opts *Target) parseOCILayoutReference() error {
} else {
// find `tag`
var err error
- path, ref, err = fileref.Parse(raw, "")
+ path, ref, err = parseModified(raw, "")
if err != nil {
return errors.Join(err, errdef.ErrInvalidReference)
}
I'm willing to open a fix once we agree on a solution.
What did you expect to happen?
oras cp should have copied the image to the remote repository
How can we reproduce it?
Set the org.opencontainers.image.ref.name annotation to something like foo:bar in index.json and try to run oras cp --from-oci-layout ./myfolder:foo:bar localhost:5000/foo:latest
What is the version of your ORAS CLI?
Manually compiled from 961e9f8
What is your OS environment?
Ubuntu 22.04 (it really doesn't matter for this bug)
Are you willing to submit PRs to fix it?
What happened in your environment?
We use OCI images to package eBPF programs in Inspektor Gadget. We have an
ig image exportcommand that creates an oci layout file with the image. I wanted to useoras cpto copy the image to a remote registry, however it fails with:The issue seems to be related to the fact that the
org.opencontainers.image.ref.nameannotation is set toghcr.io/inspektor-gadget/gadget/mygadget:latestin index.json:mygadget.tar.folder/index.json:
{ "schemaVersion": 2, "manifests": [ { "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:69fb10d45f448525a39bb26ae2af71e57fe2b7aa774547eb57da38ddf08b12e0", "size": 1278, "annotations": { "org.opencontainers.image.created": "2024-09-19T13:06:53-05:00", "org.opencontainers.image.description": "TODO: Fill the gadget description", "org.opencontainers.image.documentation": "TODO: Fill the gadget documentation URL", "org.opencontainers.image.source": "TODO: Fill the gadget source code URL", "org.opencontainers.image.title": "TODO: Fill the gadget name", "org.opencontainers.image.url": "TODO: Fill the gadget homepage URL" }, "platform": { "architecture": "arm64", "os": "linux" } }, { "mediaType": "application/vnd.oci.image.index.v1+json", "digest": "sha256:f31a444623261efcc68601704dd3d980692a73a55f5031c8ddca58cc8a23876e", "size": 1816, "annotations": { "org.opencontainers.image.created": "2024-09-19T13:06:53-05:00", "org.opencontainers.image.description": "TODO: Fill the gadget description", "org.opencontainers.image.documentation": "TODO: Fill the gadget documentation URL", "org.opencontainers.image.ref.name": "ghcr.io/inspektor-gadget/gadget/mygadget:latest", "org.opencontainers.image.source": "TODO: Fill the gadget source code URL", "org.opencontainers.image.title": "TODO: Fill the gadget name", "org.opencontainers.image.url": "TODO: Fill the gadget homepage URL" } }, { "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:f99e163810194bd7fc50e23c9f1d7d827e464aac1766892f3747b1764301c3ae", "size": 1278, "annotations": { "org.opencontainers.image.created": "2024-09-19T13:06:53-05:00", "org.opencontainers.image.description": "TODO: Fill the gadget description", "org.opencontainers.image.documentation": "TODO: Fill the gadget documentation URL", "org.opencontainers.image.source": "TODO: Fill the gadget source code URL", "org.opencontainers.image.title": "TODO: Fill the gadget name", "org.opencontainers.image.url": "TODO: Fill the gadget homepage URL" }, "platform": { "architecture": "amd64", "os": "linux" } } ] }According to https://github.com/opencontainers/image-spec/blob/v1.1.0-rc5/annotations.md,
ghcr.io/inspektor-gadget/gadget/mygadget:latestis a valid value for the annotation.Possible Fix
The following diff fixes the issue:
I'm willing to open a fix once we agree on a solution.
What did you expect to happen?
oras cpshould have copied the image to the remote repositoryHow can we reproduce it?
Set the
org.opencontainers.image.ref.nameannotation to something likefoo:barin index.json and try to runoras cp --from-oci-layout ./myfolder:foo:bar localhost:5000/foo:latestWhat is the version of your ORAS CLI?
Manually compiled from 961e9f8
What is your OS environment?
Ubuntu 22.04 (it really doesn't matter for this bug)
Are you willing to submit PRs to fix it?