pkg/registry/client.go (74 lines of code) (raw):
package registry
import (
"context"
"crypto/tls"
"fmt"
"net/http"
"path"
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"
)
//go:generate mockgen -destination=mocks/storage.go -package=mocks -source storage.go StorageClient
//go:generate mockgen -destination=mocks/repository.go -package=mocks oras.land/oras-go/v2/registry Repository
// OCIRegistryClient storage client for an OCI registry.
type OCIRegistryClient struct {
StorageContext
registry *remote.Registry
}
var _ StorageClient = (*OCIRegistryClient)(nil)
// NewOCIRegistry create an OCI registry client.
func NewOCIRegistry(sc StorageContext, registry *remote.Registry) *OCIRegistryClient {
transport := http.DefaultTransport.(*http.Transport).Clone()
{ // #nosec G402
transport.TLSClientConfig = &tls.Config{
RootCAs: sc.certificates,
InsecureSkipVerify: sc.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 sc.credentialStore.Credential(s)
}
registry.Client = authClient
return &OCIRegistryClient{
StorageContext: sc,
registry: registry,
}
}
// 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, dstStorage orasregistry.Repository, desc ocispec.Descriptor) error {
extendedCopyOptions := oras.DefaultExtendedCopyOptions
return oras.CopyGraph(ctx, srcStorage, dstStorage, desc, extendedCopyOptions.CopyGraphOptions)
}