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

fix: disable oras tag fallback to tag schema when tagging a referrer #1435

Merged
6 changes: 6 additions & 0 deletions cmd/oras/root/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/spf13/cobra"
"oras.land/oras-go/v2"
"oras.land/oras-go/v2/errdef"
"oras.land/oras-go/v2/registry/remote"
"oras.land/oras/cmd/oras/internal/argument"
"oras.land/oras/cmd/oras/internal/command"
"oras.land/oras/cmd/oras/internal/display/status"
Expand Down Expand Up @@ -102,6 +103,11 @@ func tagManifest(cmd *cobra.Command, opts *tagOptions) error {
if err != nil {
return err
}
if targetRepo, ok := target.(*remote.Repository); ok {
// Since referrer capability has not been set or detected yet,
// nil is the only returned value and thus can be ignored
_ = targetRepo.SetReferrersCapability(true)
}
if err := opts.EnsureReferenceNotEmpty(cmd, true); err != nil {
return err
}
Expand Down
50 changes: 43 additions & 7 deletions test/e2e/suite/command/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ import (
"fmt"
"path/filepath"
"regexp"
"strings"

. "github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"oras.land/oras/test/e2e/internal/testdata/foobar"
"oras.land/oras/test/e2e/internal/testdata/multi_arch"
. "oras.land/oras/test/e2e/internal/utils"
)
Expand Down Expand Up @@ -56,14 +58,15 @@ var _ = Describe("ORAS beginners:", func() {
})
})

func tagAndValidate(reg string, repo string, tagOrDigest string, digestText string, tags ...string) {
out := ORAS(append([]string{"tag", RegistryRef(reg, repo, tagOrDigest)}, tags...)...).MatchKeyWords(tags...).Exec().Out
hint := regexp.QuoteMeta(fmt.Sprintf("Tagging [registry] %s", RegistryRef(reg, repo, digestText)))
gomega.Expect(out).To(gbytes.Say(hint))
gomega.Expect(out).NotTo(gbytes.Say(hint)) // should only say hint once
ORAS("repo", "tags", RegistryRef(reg, repo, "")).MatchKeyWords(tags...).Exec()
}

var _ = Describe("1.1 registry users:", func() {
var tagAndValidate = func(reg string, repo string, tagOrDigest string, digest string, tags ...string) {
out := ORAS(append([]string{"tag", RegistryRef(reg, repo, tagOrDigest)}, tags...)...).MatchKeyWords(tags...).Exec().Out
hint := regexp.QuoteMeta(fmt.Sprintf("Tagging [registry] %s", RegistryRef(reg, repo, digest)))
gomega.Expect(out).To(gbytes.Say(hint))
gomega.Expect(out).NotTo(gbytes.Say(hint)) // should only say hint once
ORAS("repo", "tags", RegistryRef(reg, repo, "")).MatchKeyWords(tags...).Exec()
}
When("running `tag`", func() {
It("should add a tag to an existent manifest when providing tag reference", func() {
tagAndValidate(ZOTHost, ImageRepo, multi_arch.Tag, multi_arch.Digest, "tag-via-tag")
Expand All @@ -77,6 +80,39 @@ var _ = Describe("1.1 registry users:", func() {
It("should add multiple tags to an existent manifest when providing tag reference", func() {
tagAndValidate(ZOTHost, ImageRepo, multi_arch.Tag, multi_arch.Digest, "tag1-via-tag", "tag1-via-tag", "tag1-via-tag")
})
It("should tag a referrer witout tag schema", func() {
// parepare:
repo := fmt.Sprintf("command/tag/%d/referrers", GinkgoRandomSeed())
ORAS("cp", "-r", RegistryRef(ZOTHost, ArtifactRepo, foobar.Tag), "--to-distribution-spec", "v1.1-referrers-api", RegistryRef(ZOTHost, repo, foobar.Tag)).Exec()
// test
referrerDigest := foobar.SBOMImageReferrer.Digest.String()
tagAndValidate(ZOTHost, repo, referrerDigest, referrerDigest, "tagged-referrer")
// ensure no referrer index is created
ref := RegistryRef(ZOTHost, repo, strings.Replace(foobar.Digest, ":", "-", 1))
ORAS("manifest", "fetch", ref).
MatchErrKeyWords(fmt.Sprintf("%s: not found", ref)).
ExpectFailure().
Exec()
})
})
})

var _ = Describe("1.0 registry users:", func() {
When("running `tag`", func() {
It("should tag a referrer witout tag schema", func() {
// prepare: copy to the fallback registry
repo := fmt.Sprintf("command/tag/%d/referrers", GinkgoRandomSeed())
ORAS("cp", "-r", RegistryRef(FallbackHost, ArtifactRepo, foobar.Tag), "--to-distribution-spec", "v1.1-referrers-api", RegistryRef(FallbackHost, repo, foobar.Tag)).Exec()
// test
referrerDigest := foobar.SBOMImageReferrer.Digest.String()
tagAndValidate(FallbackHost, repo, referrerDigest, referrerDigest, "tagged-referrer")
// ensure no referrer index is created
indexReferrerTag := RegistryRef(FallbackHost, repo, strings.Replace(foobar.Digest, ":", "-", 1))
ORAS("manifest", "fetch", indexReferrerTag).
MatchErrKeyWords(fmt.Sprintf("%s: not found", indexReferrerTag)).
ExpectFailure().
Exec()
})
})
})

Expand Down
Loading