Merge pull request #52 from docker/refactor-use-interface-value

refactor: use interface value
This commit is contained in:
Joel Kamp
2024-06-14 11:58:45 -05:00
committed by GitHub
9 changed files with 74 additions and 72 deletions

View File

@@ -47,7 +47,7 @@ func ExampleSign_remote() {
}
// push image index with signed attestation-manifests
err = mirror.PushToRegistry(signedImageIndex, ref)
err = mirror.PushIndexToRegistry(signedImageIndex, ref)
if err != nil {
panic(err)
}
@@ -62,7 +62,7 @@ func ExampleSign_remote() {
},
},
})
err = mirror.SaveAsOCILayout(idx, path)
err = mirror.SaveIndexAsOCILayout(idx, path)
if err != nil {
panic(err)
}

View File

@@ -61,7 +61,7 @@ func TestAttestationReferenceTypes(t *testing.T) {
indexName := fmt.Sprintf("%s/repo:root", u.Host)
require.NoError(t, err)
err = mirror.PushToRegistry(signedIndex, indexName)
err = mirror.PushIndexToRegistry(signedIndex, indexName)
for _, platform := range platforms {
// can eval policy in the normal way
@@ -121,7 +121,7 @@ func TestReferencesInDifferentRepo(t *testing.T) {
require.NoError(t, err)
indexName := fmt.Sprintf("%s/%s:latest", serverUrl.Host, repoName)
err = mirror.PushToRegistry(attIdx.Index, indexName)
err = mirror.PushIndexToRegistry(attIdx.Index, indexName)
require.NoError(t, err)
signedImages, err := attest.SignedAttestationImages(ctx, attIdx.Index, signer, opts)
@@ -130,7 +130,7 @@ func TestReferencesInDifferentRepo(t *testing.T) {
// push signed attestation image to the ref server
for _, img := range signedImages {
// push references using subject-digest.att convention
err = mirror.PushToRegistry(img.Image, fmt.Sprintf("%s/%s:tag-does-not-matter", refServerUrl.Host, repoName))
err = mirror.PushImageToRegistry(img.Image, fmt.Sprintf("%s/%s:tag-does-not-matter", refServerUrl.Host, repoName))
require.NoError(t, err)
}
mfs2, err := attIdx.Index.IndexManifest()

View File

@@ -13,7 +13,7 @@ import (
)
type TufMirrorOutput struct {
metadata *v1.Image
metadata v1.Image
delegatedMetadata []*mirror.MirrorImage
targets []*mirror.MirrorImage
delegatedTargets []*mirror.MirrorIndex
@@ -80,7 +80,7 @@ func ExampleNewTufMirror() {
func mirrorToRegistry(o *TufMirrorOutput) error {
// push metadata to registry
metadataRepo := "registry-1.docker.io/docker/tuf-metadata:latest"
err := mirror.PushToRegistry(o.metadata, metadataRepo)
err := mirror.PushImageToRegistry(o.metadata, metadataRepo)
if err != nil {
return err
}
@@ -91,7 +91,7 @@ func mirrorToRegistry(o *TufMirrorOutput) error {
return fmt.Errorf("failed to get repo without tag: %s", metadataRepo)
}
imageName := fmt.Sprintf("%s:%s", repo, metadata.Tag)
err = mirror.PushToRegistry(metadata.Image, imageName)
err = mirror.PushImageToRegistry(metadata.Image, imageName)
if err != nil {
return err
}
@@ -101,7 +101,7 @@ func mirrorToRegistry(o *TufMirrorOutput) error {
targetsRepo := "registry-1.docker.io/docker/tuf-targets"
for _, target := range o.targets {
imageName := fmt.Sprintf("%s:%s", targetsRepo, target.Tag)
err = mirror.PushToRegistry(target.Image, imageName)
err = mirror.PushImageToRegistry(target.Image, imageName)
if err != nil {
return err
}
@@ -109,7 +109,7 @@ func mirrorToRegistry(o *TufMirrorOutput) error {
// push delegated targets to registry
for _, target := range o.delegatedTargets {
imageName := fmt.Sprintf("%s:%s", targetsRepo, target.Tag)
err = mirror.PushToRegistry(target.Index, imageName)
err = mirror.PushIndexToRegistry(target.Index, imageName)
if err != nil {
return err
}
@@ -119,14 +119,14 @@ func mirrorToRegistry(o *TufMirrorOutput) error {
func mirrorToLocal(o *TufMirrorOutput, outputPath string) error {
// output metadata to local directory
err := mirror.SaveAsOCILayout(o.metadata, outputPath)
err := mirror.SaveImageAsOCILayout(o.metadata, outputPath)
if err != nil {
return err
}
// output delegated metadata to local directory
for _, metadata := range o.delegatedMetadata {
path := filepath.Join(outputPath, metadata.Tag)
err = mirror.SaveAsOCILayout(metadata.Image, path)
err = mirror.SaveImageAsOCILayout(metadata.Image, path)
if err != nil {
return err
}
@@ -135,7 +135,7 @@ func mirrorToLocal(o *TufMirrorOutput, outputPath string) error {
// output top-level targets to local directory
for _, target := range o.targets {
path := filepath.Join(outputPath, target.Tag)
err = mirror.SaveAsOCILayout(target.Image, path)
err = mirror.SaveImageAsOCILayout(target.Image, path)
if err != nil {
return err
}
@@ -143,7 +143,7 @@ func mirrorToLocal(o *TufMirrorOutput, outputPath string) error {
// output delegated targets to local directory
for _, target := range o.delegatedTargets {
path := filepath.Join(outputPath, target.Tag)
err = mirror.SaveAsOCILayout(target.Index, path)
err = mirror.SaveIndexAsOCILayout(target.Index, path)
if err != nil {
return err
}

View File

@@ -17,7 +17,7 @@ import (
// -----------------
// GetMetadataManifest returns an image with TUF root metadata as layers
func (m *TufMirror) GetMetadataManifest(metadataURL string) (*v1.Image, error) {
func (m *TufMirror) GetMetadataManifest(metadataURL string) (v1.Image, error) {
metadata, err := m.getTufMetadataMirror(metadataURL)
if err != nil {
return nil, fmt.Errorf("failed to get metadata: %w", err)
@@ -78,7 +78,7 @@ func (m *TufMirror) getTufMetadataMirror(metadataURL string) (*TufMetadata, erro
}
// buildMetadataManifest returns an OCI image with TUF metadata as layers with annotations
func (m *TufMirror) buildMetadataManifest(metadata *TufMetadata) (*v1.Image, error) {
func (m *TufMirror) buildMetadataManifest(metadata *TufMetadata) (v1.Image, error) {
img := empty.Image
img = mutate.MediaType(img, types.OCIManifestSchema1)
img = mutate.ConfigMediaType(img, types.OCIConfigJSON)
@@ -87,17 +87,17 @@ func (m *TufMirror) buildMetadataManifest(metadata *TufMetadata) (*v1.Image, err
if err != nil {
return nil, fmt.Errorf("failed to make role layer: %w", err)
}
img, err = mutate.Append(img, *layers...)
img, err = mutate.Append(img, layers...)
if err != nil {
return nil, fmt.Errorf("failed to append role layer to image: %w", err)
}
}
return &img, nil
return img, nil
}
// makeRoleLayers returns a list of layers for a given TUF role
func (m *TufMirror) makeRoleLayers(role TufRole, tufMetadata *TufMetadata) (*[]mutate.Addendum, error) {
layers := new([]mutate.Addendum)
func (m *TufMirror) makeRoleLayers(role TufRole, tufMetadata *TufMetadata) ([]mutate.Addendum, error) {
var layers []mutate.Addendum
ann := map[string]string{tufFileAnnotation: ""}
switch role {
case metadata.ROOT:
@@ -108,7 +108,7 @@ func (m *TufMirror) makeRoleLayers(role TufRole, tufMetadata *TufMetadata) (*[]m
layers = m.annotatedMetaLayers(tufMetadata.Targets)
case metadata.TIMESTAMP:
ann[tufFileAnnotation] = fmt.Sprintf("%s.json", role)
*layers = append(*layers, mutate.Addendum{Layer: static.NewLayer(tufMetadata.Timestamp, tufMetadataMediaType), Annotations: ann})
layers = append(layers, mutate.Addendum{Layer: static.NewLayer(tufMetadata.Timestamp, tufMetadataMediaType), Annotations: ann})
default:
return nil, fmt.Errorf("unsupported TUF role: %s", role)
}
@@ -116,11 +116,11 @@ func (m *TufMirror) makeRoleLayers(role TufRole, tufMetadata *TufMetadata) (*[]m
}
// annotatedMetaLayers returns a list of layers with annotations for each TUF metadata file
func (m *TufMirror) annotatedMetaLayers(meta map[string][]byte) *[]mutate.Addendum {
layers := new([]mutate.Addendum)
func (m *TufMirror) annotatedMetaLayers(meta map[string][]byte) []mutate.Addendum {
var layers []mutate.Addendum
for name, data := range meta {
ann := map[string]string{tufFileAnnotation: name}
*layers = append(*layers, mutate.Addendum{Layer: static.NewLayer(data, tufMetadataMediaType), Annotations: ann})
layers = append(layers, mutate.Addendum{Layer: static.NewLayer(data, tufMetadataMediaType), Annotations: ann})
}
return layers
}
@@ -144,8 +144,8 @@ func (m *TufMirror) GetDelegatedMetadataMirrors() ([]*MirrorImage, error) {
}
// getDelegatedTargetsMetadata returns delegated targets metadata as a list of DelegatedTargetMetadata (role name and data)
func (m *TufMirror) getDelegatedTargetsMetadata() (*[]DelegatedTargetMetadata, error) {
delegatedTargets := new([]DelegatedTargetMetadata)
func (m *TufMirror) getDelegatedTargetsMetadata() ([]DelegatedTargetMetadata, error) {
var delegatedTargets []DelegatedTargetMetadata
md := m.TufClient.GetMetadata()
for _, role := range md.Targets[metadata.TARGETS].Signed.Delegations.Roles {
roleMetadata, err := m.TufClient.LoadDelegatedTargets(role.Name, metadata.TARGETS)
@@ -165,15 +165,15 @@ func (m *TufMirror) getDelegatedTargetsMetadata() (*[]DelegatedTargetMetadata, e
if md.Root.Signed.ConsistentSnapshot {
version = strconv.FormatInt(meta.Version, 10)
}
*delegatedTargets = append(*delegatedTargets, DelegatedTargetMetadata{Name: role.Name, Version: version, Data: roleBytes})
delegatedTargets = append(delegatedTargets, DelegatedTargetMetadata{Name: role.Name, Version: version, Data: roleBytes})
}
return delegatedTargets, nil
}
// buildDelegatedMetadataManifests returns a list of mirrors (image/tag pairs) for each delegated target role metadata
func (m *TufMirror) buildDelegatedMetadataManifests(delegated *[]DelegatedTargetMetadata) ([]*MirrorImage, error) {
func (m *TufMirror) buildDelegatedMetadataManifests(delegated []DelegatedTargetMetadata) ([]*MirrorImage, error) {
manifests := []*MirrorImage{}
for _, role := range *delegated {
for _, role := range delegated {
img := empty.Image
img = mutate.MediaType(img, types.OCIManifestSchema1)
img = mutate.ConfigMediaType(img, types.OCIConfigJSON)
@@ -183,7 +183,7 @@ func (m *TufMirror) buildDelegatedMetadataManifests(delegated *[]DelegatedTarget
if err != nil {
return nil, fmt.Errorf("failed to append delegated targets layer to image: %w", err)
}
manifests = append(manifests, &MirrorImage{Image: &img, Tag: role.Name})
manifests = append(manifests, &MirrorImage{Image: img, Tag: role.Name})
}
return manifests, nil
}

View File

@@ -46,8 +46,7 @@ func TestGetMetadataManifest(t *testing.T) {
assert.NoError(t, err)
assert.NotNil(t, img)
image := *img
mf, err := image.RawManifest()
mf, err := img.RawManifest()
assert.NoError(t, err)
type Annotations struct {

View File

@@ -26,7 +26,7 @@ func NewTufMirror(root []byte, tufPath, metadataURL, targetsURL string, versionC
return &TufMirror{TufClient: tufClient, tufPath: tufPath, metadataURL: metadataURL, targetsURL: targetsURL}, nil
}
func PushToRegistry(image any, imageName string) error {
func PushImageToRegistry(image v1.Image, imageName string) error {
// Parse the image name
ref, err := name.ParseReference(imageName)
if err != nil {
@@ -38,45 +38,48 @@ func PushToRegistry(image any, imageName string) error {
log.Fatalf("Failed to get authenticator: %v", err)
}
// Push the image to the registry
switch image := image.(type) {
case v1.Image:
if err := remote.Write(ref, image, remote.WithAuth(auth)); err != nil {
return fmt.Errorf("failed to push image %s: %w", imageName, err)
}
case v1.ImageIndex:
if err := remote.WriteIndex(ref, image, remote.WithAuth(auth)); err != nil {
return fmt.Errorf("failed to push image index %s: %w", imageName, err)
}
default:
return fmt.Errorf("unknown image type")
}
return nil
return remote.Write(ref, image, remote.WithAuth(auth))
}
func SaveAsOCILayout(image any, path string) error {
func PushIndexToRegistry(image v1.ImageIndex, imageName string) error {
// Parse the index name
ref, err := name.ParseReference(imageName)
if err != nil {
log.Fatalf("Failed to parse image name: %v", err)
}
// Get the authenticator from the default Docker keychain
auth, err := authn.DefaultKeychain.Resolve(ref.Context())
if err != nil {
log.Fatalf("Failed to get authenticator: %v", err)
}
// Push the index to the registry
return remote.WriteIndex(ref, image, remote.WithAuth(auth))
}
func SaveImageAsOCILayout(image v1.Image, path string) error {
// Save the image to the local filesystem
err := os.MkdirAll(path, os.FileMode(0744))
err := os.MkdirAll(path, os.FileMode(0755))
if err != nil {
return fmt.Errorf("failed to create directory: %w", err)
}
switch image := image.(type) {
case v1.Image:
index := empty.Index
l, err := layout.Write(path, index)
if err != nil {
return fmt.Errorf("failed to create index: %w", err)
}
err = l.AppendImage(image)
if err != nil {
return fmt.Errorf("failed to append image to index: %w", err)
}
case v1.ImageIndex:
_, err := layout.Write(path, image)
if err != nil {
return fmt.Errorf("failed to create index: %w", err)
}
default:
return fmt.Errorf("unknown image type")
index := empty.Index
l, err := layout.Write(path, index)
if err != nil {
return fmt.Errorf("failed to create index: %w", err)
}
return l.AppendImage(image)
}
func SaveIndexAsOCILayout(image v1.ImageIndex, path string) error {
// Save the index to the local filesystem
err := os.MkdirAll(path, os.FileMode(0755))
if err != nil {
return fmt.Errorf("failed to create directory: %w", err)
}
_, err = layout.Write(path, image)
if err != nil {
return fmt.Errorf("failed to create index: %w", err)
}
return nil
}

View File

@@ -42,7 +42,7 @@ func (m *TufMirror) GetTufTargetMirrors() ([]*MirrorImage, error) {
if err != nil {
return nil, fmt.Errorf("failed to append role layer to image: %w", err)
}
targetMirrors = append(targetMirrors, &MirrorImage{Image: &img, Tag: name})
targetMirrors = append(targetMirrors, &MirrorImage{Image: img, Tag: name})
}
return targetMirrors, nil
}
@@ -103,7 +103,7 @@ func (m *TufMirror) GetDelegatedTargetMirrors() ([]*MirrorIndex, error) {
},
})
}
mirror = append(mirror, &MirrorIndex{Index: &index, Tag: role.Name})
mirror = append(mirror, &MirrorIndex{Index: index, Tag: role.Name})
}
return mirror, nil
}

View File

@@ -36,7 +36,7 @@ func TestGetTufTargetsMirror(t *testing.T) {
// check for image layer annotations
for _, target := range targets {
img := *target.Image
img := target.Image
mf, err := img.RawManifest()
assert.NoError(t, err)
@@ -83,7 +83,7 @@ func TestGetDelegatedTargetMirrors(t *testing.T) {
// check for index image annotations
for _, mirror := range mirrors {
idx := *mirror.Index
idx := mirror.Index
mf, err := idx.RawManifest()
assert.NoError(t, err)

View File

@@ -32,12 +32,12 @@ type DelegatedTargetMetadata struct {
}
type MirrorImage struct {
Image *v1.Image
Image v1.Image
Tag string
}
type MirrorIndex struct {
Index *v1.ImageIndex
Index v1.ImageIndex
Tag string
}