/
client.go
117 lines (101 loc) 路 3.67 KB
/
client.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
package registry
import (
"context"
"crypto/tls"
"fmt"
"net/http"
"path"
"sync"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras-go/v2"
"oras.land/oras-go/v2/content"
orasregistry "oras.land/oras-go/v2/registry"
"oras.land/oras-go/v2/registry/remote"
"oras.land/oras-go/v2/registry/remote/auth"
)
// OCIRegistryClient storage client for an OCI registry.
type OCIRegistryClient struct {
StorageContext
initialized sync.Once
registry *remote.Registry
}
var _ StorageClient = (*OCIRegistryClient)(nil)
// NewOCIRegistry create an OCI registry client.
func NewOCIRegistry(context StorageContext) *OCIRegistryClient {
return &OCIRegistryClient{
StorageContext: context,
}
}
// Init registry configuration.
func (or *OCIRegistryClient) Init() error {
var err error
onceFunc := func() {
or.registry, err = remote.NewRegistry(or.host)
if err != nil {
err = fmt.Errorf("error with registry <%s>: %v", or.host, err)
return
}
transport := http.DefaultTransport.(*http.Transport).Clone()
{ // #nosec G402
transport.TLSClientConfig = &tls.Config{
RootCAs: or.certificates,
InsecureSkipVerify: or.insecure,
}
}
authClient := &auth.Client{
Client: &http.Client{
Transport: transport,
},
Cache: auth.NewCache(),
}
authClient.SetUserAgent("eksa")
authClient.Credential = func(ctx context.Context, s string) (auth.Credential, error) {
return or.credentialStore.Credential(s)
}
or.registry.Client = authClient
}
or.initialized.Do(onceFunc)
return err
}
// GetHost for registry host.
func (or *OCIRegistryClient) GetHost() string {
return or.host
}
// SetProject for registry destination.
func (or *OCIRegistryClient) SetProject(project string) {
or.project = project
}
// Destination of this storage registry.
func (or *OCIRegistryClient) Destination(image Artifact) string {
return path.Join(or.host, or.project, image.Repository) + image.Version()
}
// GetStorage object based on repository.
func (or *OCIRegistryClient) GetStorage(ctx context.Context, artifact Artifact) (repo orasregistry.Repository, err error) {
dstRepo := path.Join(or.project, artifact.Repository)
repo, err = or.registry.Repository(ctx, dstRepo)
if err != nil {
return nil, fmt.Errorf("error creating repository %s: %v", dstRepo, err)
}
return repo, nil
}
// Resolve the location of the source repository given the image.
func (or *OCIRegistryClient) Resolve(ctx context.Context, srcStorage orasregistry.Repository, versionedImage string) (desc ocispec.Descriptor, err error) {
or.registry.Reference.Reference = versionedImage
return srcStorage.Resolve(ctx, or.registry.Reference.Reference)
}
// FetchBytes a resource from the registry.
func (or *OCIRegistryClient) FetchBytes(ctx context.Context, srcStorage orasregistry.Repository, artifact Artifact) (ocispec.Descriptor, []byte, error) {
return oras.FetchBytes(ctx, srcStorage, artifact.VersionedImage(), oras.DefaultFetchBytesOptions)
}
// FetchBlob get named blob.
func (or *OCIRegistryClient) FetchBlob(ctx context.Context, srcStorage orasregistry.Repository, descriptor ocispec.Descriptor) ([]byte, error) {
return content.FetchAll(ctx, srcStorage, descriptor)
}
// CopyGraph copy manifest and all blobs to destination.
func (or *OCIRegistryClient) CopyGraph(ctx context.Context, srcStorage orasregistry.Repository, srcRef string, dstStorage orasregistry.Repository, dstRef string) (ocispec.Descriptor, error) {
return oras.Copy(ctx, srcStorage, srcRef, dstStorage, dstRef, oras.CopyOptions{})
}
// Tag an image.
func (or *OCIRegistryClient) Tag(ctx context.Context, dstStorage orasregistry.Repository, desc ocispec.Descriptor, tag string) error {
return dstStorage.Tag(ctx, desc, tag)
}