/
tag.go
95 lines (90 loc) · 2.1 KB
/
tag.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package ocidir
import (
"context"
"encoding/json"
"fmt"
"sort"
"strings"
"github.com/regclient/regclient/scheme"
"github.com/regclient/regclient/types/errs"
"github.com/regclient/regclient/types/mediatype"
"github.com/regclient/regclient/types/ref"
"github.com/regclient/regclient/types/tag"
)
// TagDelete removes a tag from the repository
func (o *OCIDir) TagDelete(ctx context.Context, r ref.Ref) error {
o.mu.Lock()
defer o.mu.Unlock()
return o.tagDelete(ctx, r)
}
func (o *OCIDir) tagDelete(_ context.Context, r ref.Ref) error {
if r.Tag == "" {
return errs.ErrMissingTag
}
// get index
index, err := o.readIndex(r, true)
if err != nil {
return fmt.Errorf("failed to read index: %w", err)
}
changed := false
for i, desc := range index.Manifests {
if t, ok := desc.Annotations[aOCIRefName]; ok && t == r.Tag {
// remove matching entry from index
index.Manifests = append(index.Manifests[:i], index.Manifests[i+1:]...)
changed = true
}
}
if !changed {
return fmt.Errorf("failed deleting %s: %w", r.CommonName(), errs.ErrNotFound)
}
// push manifest back out
err = o.writeIndex(r, index, true)
if err != nil {
return fmt.Errorf("failed to write index: %w", err)
}
o.refMod(r)
return nil
}
// TagList returns a list of tags from the repository
func (o *OCIDir) TagList(ctx context.Context, r ref.Ref, opts ...scheme.TagOpts) (*tag.List, error) {
// get index
index, err := o.readIndex(r, false)
if err != nil {
return nil, err
}
tl := []string{}
for _, desc := range index.Manifests {
if t, ok := desc.Annotations[aOCIRefName]; ok {
if i := strings.LastIndex(t, ":"); i >= 0 {
t = t[i+1:]
}
found := false
for _, cur := range tl {
if cur == t {
found = true
break
}
}
if !found {
tl = append(tl, t)
}
}
}
sort.Strings(tl)
ib, err := json.Marshal(index)
if err != nil {
return nil, err
}
// return listing from index
t, err := tag.New(
tag.WithRaw(ib),
tag.WithRef(r),
tag.WithMT(mediatype.OCI1ManifestList),
tag.WithLayoutIndex(index),
tag.WithTags(tl),
)
if err != nil {
return nil, err
}
return t, nil
}