forked from buildpacks/imgutil
-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.go
141 lines (117 loc) · 3.2 KB
/
util.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package imgutil
import (
"encoding/json"
"slices"
"strings"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/empty"
"github.com/google/go-containerregistry/pkg/v1/mutate"
"github.com/google/go-containerregistry/pkg/v1/partial"
"github.com/google/go-containerregistry/pkg/v1/types"
"github.com/pkg/errors"
)
func GetConfigFile(image v1.Image) (*v1.ConfigFile, error) {
configFile, err := image.ConfigFile()
if err != nil {
return nil, err
}
if configFile == nil {
return nil, errors.New("missing config file")
}
return configFile, nil
}
func GetManifest(image v1.Image) (*v1.Manifest, error) {
manifest, err := image.Manifest()
if err != nil {
return nil, err
}
if manifest == nil {
return nil, errors.New("missing manifest")
}
return manifest, nil
}
// TaggableIndex any ImageIndex with RawManifest method.
type TaggableIndex struct {
*v1.IndexManifest
}
// RawManifest returns the bytes of IndexManifest.
func (t *TaggableIndex) RawManifest() ([]byte, error) {
return json.Marshal(t.IndexManifest)
}
// Digest returns the Digest of the IndexManifest if present.
// Else generate a new Digest.
func (t *TaggableIndex) Digest() (v1.Hash, error) {
if t.IndexManifest.Subject != nil && t.IndexManifest.Subject.Digest != (v1.Hash{}) {
return t.IndexManifest.Subject.Digest, nil
}
return partial.Digest(t)
}
// MediaType returns the MediaType of the IndexManifest.
func (t *TaggableIndex) MediaType() (types.MediaType, error) {
return t.IndexManifest.MediaType, nil
}
// Size returns the Size of IndexManifest if present.
// Calculate the Size of empty.
func (t *TaggableIndex) Size() (int64, error) {
if t.IndexManifest.Subject != nil && t.IndexManifest.Subject.Size != 0 {
return t.IndexManifest.Subject.Size, nil
}
return partial.Size(t)
}
type StringSet struct {
items map[string]bool
}
func NewStringSet() *StringSet {
return &StringSet{items: make(map[string]bool)}
}
func (s *StringSet) Add(str string) {
if s == nil {
s = &StringSet{items: make(map[string]bool)}
}
s.items[str] = true
}
func (s *StringSet) Remove(str string) {
if s == nil {
s = &StringSet{items: make(map[string]bool)}
}
s.items[str] = false
}
func (s *StringSet) StringSlice() (slice []string) {
if s == nil {
s = &StringSet{items: make(map[string]bool)}
}
for i, ok := range s.items {
if ok {
slice = append(slice, i)
}
}
return slice
}
func MapContains(src, target map[string]string) bool {
for targetKey, targetValue := range target {
if value := src[targetKey]; targetValue == value {
continue
}
return false
}
return true
}
func SliceContains(src, target []string) bool {
for _, value := range target {
if ok := slices.Contains[[]string, string](src, value); !ok {
return false
}
}
return true
}
// MakeFileSafeName Change a reference name string into a valid file name
// Ex: cnbs/sample-package:hello-multiarch-universe
// to cnbs_sample-package-hello-multiarch-universe
func MakeFileSafeName(ref string) string {
fileName := strings.ReplaceAll(ref, ":", "-")
return strings.ReplaceAll(fileName, "/", "_")
}
func NewEmptyDockerIndex() v1.ImageIndex {
idx := empty.Index
return mutate.IndexMediaType(idx, types.DockerManifestList)
}