Skip to content

Commit 77f98d6

Browse files
committed
handle implicit version part of an artifact identity
1 parent a60c79f commit 77f98d6

File tree

16 files changed

+279
-121
lines changed

16 files changed

+279
-121
lines changed

api/helper/builder/ocm_identity.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package builder
22

3+
import (
4+
metav1 "ocm.software/ocm/api/ocm/compdesc/meta/v1"
5+
)
6+
37
const T_OCMMETA = "element with metadata"
48

59
////////////////////////////////////////////////////////////////////////////////
@@ -10,6 +14,18 @@ func (b *Builder) ExtraIdentity(name string, value string) {
1014
b.ocm_meta.ExtraIdentity.Set(name, value)
1115
}
1216

17+
func (b *Builder) ExtraIdentities(extras ...string) {
18+
b.expect(b.ocm_meta, T_OCMMETA)
19+
20+
id := metav1.NewExtraIdentity(extras...)
21+
if b.ocm_meta.ExtraIdentity == nil {
22+
b.ocm_meta.ExtraIdentity = metav1.Identity{}
23+
}
24+
for k, v := range id {
25+
b.ocm_meta.ExtraIdentity.Set(k, v)
26+
}
27+
}
28+
1329
////////////////////////////////////////////////////////////////////////////////
1430

1531
func (b *Builder) RemoveExtraIdentity(name string) {

api/oci/art_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ var _ = Describe("art parsing", func() {
2626
It("succeeds", func() {
2727
CheckArt("ubuntu", &oci.ArtSpec{Repository: "ubuntu"})
2828
CheckArt("ubuntu/test", &oci.ArtSpec{Repository: "ubuntu/test"})
29-
CheckArt("ubuntu/test@"+digest.String(), &oci.ArtSpec{Repository: "ubuntu/test", Digest: &digest})
30-
CheckArt("ubuntu/test:"+tag, &oci.ArtSpec{Repository: "ubuntu/test", Tag: &tag})
31-
CheckArt("ubuntu/test:"+tag+"@"+digest.String(), &oci.ArtSpec{Repository: "ubuntu/test", Digest: &digest, Tag: &tag})
29+
CheckArt("ubuntu/test@"+digest.String(), &oci.ArtSpec{Repository: "ubuntu/test", ArtVersion: oci.ArtVersion{Digest: &digest}})
30+
CheckArt("ubuntu/test:"+tag, &oci.ArtSpec{Repository: "ubuntu/test", ArtVersion: oci.ArtVersion{Tag: &tag}})
31+
CheckArt("ubuntu/test:"+tag+"@"+digest.String(), &oci.ArtSpec{Repository: "ubuntu/test", ArtVersion: oci.ArtVersion{Digest: &digest, Tag: &tag}})
3232
})
3333

3434
It("fails", func() {

api/oci/extensions/repositories/artifactset/utils_synthesis.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"ocm.software/ocm/api/oci/artdesc"
1313
"ocm.software/ocm/api/oci/cpi"
14+
"ocm.software/ocm/api/oci/ociutils"
1415
"ocm.software/ocm/api/oci/tools/transfer"
1516
"ocm.software/ocm/api/oci/tools/transfer/filters"
1617
"ocm.software/ocm/api/utils/accessio"
@@ -92,14 +93,19 @@ func SynthesizeArtifactBlobForArtifact(art cpi.ArtifactAccess, ref string, filte
9293
return nil, err
9394
}
9495

96+
vers, err := ociutils.ParseVersion(ref)
97+
if err != nil {
98+
return nil, err
99+
}
100+
95101
return SythesizeArtifactSet(func(set *ArtifactSet) (string, error) {
96102
dig, err := transfer.TransferArtifactWithFilter(art, set, filters.And(filter...))
97103
if err != nil {
98104
return "", fmt.Errorf("failed to transfer artifact: %w", err)
99105
}
100106

101-
if ok, _ := artdesc.IsDigest(ref); !ok {
102-
err = set.AddTags(*dig, ref)
107+
if ok := vers.IsTagged(); ok {
108+
err = set.AddTags(*dig, vers.GetTag())
103109
if err != nil {
104110
return "", fmt.Errorf("failed to add tag: %w", err)
105111
}

api/oci/ociutils/ref.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package ociutils
2+
3+
import (
4+
"strings"
5+
6+
"github.com/mandelsoft/goutils/generics"
7+
"github.com/opencontainers/go-digest"
8+
)
9+
10+
// ParseVersion parses the version part of an OCI reference consisting
11+
// of an optional tag and/or digest.
12+
func ParseVersion(vers string) (ArtVersion, error) {
13+
if strings.HasPrefix(vers, "@") {
14+
dig, err := digest.Parse(vers[1:])
15+
if err != nil {
16+
return ArtVersion{}, err
17+
}
18+
return ArtVersion{
19+
Tag: nil,
20+
Digest: &dig,
21+
}, nil
22+
}
23+
24+
i := strings.Index(vers, "@")
25+
if i > 0 {
26+
dig, err := digest.Parse(vers[i+1:])
27+
if err != nil {
28+
return ArtVersion{}, err
29+
}
30+
return ArtVersion{
31+
Tag: generics.Pointer(vers[:i]),
32+
Digest: &dig,
33+
}, nil
34+
}
35+
return ArtVersion{
36+
Tag: &vers,
37+
}, nil
38+
}
39+
40+
// ArtVersion is the version part of an OCI reference consisting of an
41+
// optional tag and/or digest. Both parts may be nil, if a reference
42+
// does not include a version part.
43+
type ArtVersion struct {
44+
// +optional
45+
Tag *string `json:"tag,omitempty"`
46+
// +optional
47+
Digest *digest.Digest `json:"digest,omitempty"`
48+
}
49+
50+
func (v *ArtVersion) VersionSpec() string {
51+
vers := ""
52+
if v != nil {
53+
if v.Tag != nil {
54+
vers = *v.Tag
55+
}
56+
if v.Digest != nil {
57+
vers += "@" + string(*v.Digest)
58+
}
59+
if vers == "" {
60+
return "latest"
61+
}
62+
}
63+
return vers
64+
}
65+
66+
func (v *ArtVersion) IsVersion() bool {
67+
return v.Tag != nil || v.Digest != nil
68+
}
69+
70+
func (v *ArtVersion) IsTagged() bool {
71+
return v.Tag != nil
72+
}
73+
74+
func (v *ArtVersion) IsDigested() bool {
75+
return v.Digest != nil
76+
}
77+
78+
func (v *ArtVersion) GetTag() string {
79+
if v.Tag != nil {
80+
return *v.Tag
81+
}
82+
return ""
83+
}

api/oci/ref.go

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/opencontainers/go-digest"
99

1010
"ocm.software/ocm/api/oci/grammar"
11+
"ocm.software/ocm/api/oci/ociutils"
1112
)
1213

1314
// to find a suitable secret for images on Docker Hub, we need its two domains to do matching.
@@ -224,6 +225,10 @@ func (r RefSpec) DeepCopy() RefSpec {
224225

225226
////////////////////////////////////////////////////////////////////////////////
226227

228+
func ParseVersion(vers string) (ArtVersion, error) {
229+
return ociutils.ParseVersion(vers)
230+
}
231+
227232
func ParseArt(art string) (ArtSpec, error) {
228233
match := grammar.AnchoredArtifactVersionRegexp.FindSubmatch([]byte(art))
229234

@@ -247,19 +252,21 @@ func ParseArt(art string) (ArtSpec, error) {
247252
}
248253
return ArtSpec{
249254
Repository: string(match[1]),
250-
Tag: tag,
251-
Digest: dig,
255+
ArtVersion: ArtVersion{
256+
Tag: tag,
257+
Digest: dig,
258+
},
252259
}, nil
253260
}
254261

262+
type ArtVersion = ociutils.ArtVersion
263+
255264
// ArtSpec is a go internal representation of a oci reference.
256265
type ArtSpec struct {
257266
// Repository is the part of a reference without its hostname
258267
Repository string `json:"repository"`
259-
// +optional
260-
Tag *string `json:"tag,omitempty"`
261-
// +optional
262-
Digest *digest.Digest `json:"digest,omitempty"`
268+
// artifact version
269+
ArtVersion `json:",inline"`
263270
}
264271

265272
func (r *ArtSpec) Version() string {
@@ -276,21 +283,6 @@ func (r *ArtSpec) IsRegistry() bool {
276283
return r.Repository == ""
277284
}
278285

279-
func (r *ArtSpec) IsVersion() bool {
280-
return r.Tag != nil || r.Digest != nil
281-
}
282-
283-
func (r *ArtSpec) IsTagged() bool {
284-
return r.Tag != nil
285-
}
286-
287-
func (r *ArtSpec) GetTag() string {
288-
if r.Tag != nil {
289-
return *r.Tag
290-
}
291-
return ""
292-
}
293-
294286
func (r *ArtSpec) String() string {
295287
s := r.Repository
296288
if r.Tag != nil {

0 commit comments

Comments
 (0)