Skip to content

Commit

Permalink
Generalise fetcher function, incorporate raw manifests
Browse files Browse the repository at this point in the history
  • Loading branch information
errordeveloper committed Sep 25, 2023
1 parent f2448b1 commit 7071da6
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 14 deletions.
2 changes: 1 addition & 1 deletion manifest/imageresolver/imageresolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (c *RegistryResolver) FindRelatedFromIndecies(ctx context.Context, images *
manifests := types.NewImageList(images.Dir())
for i := range images.Items() {
image := images.Items()[i]
imageIndex, indexManifest, _, err := c.IndexOrImage(ctx, image.Ref(true))
imageIndex, indexManifest, _, err := c.GetIndexOrImage(ctx, image.Ref(true))
if err != nil {
return nil, nil, err
}
Expand Down
45 changes: 35 additions & 10 deletions oci/artefact.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"compress/gzip"
"context"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"maps"
Expand Down Expand Up @@ -42,25 +43,27 @@ const (
// TODO: content interpreter invocation with an image

regularFileMode = 0o640

OCIManifestSchema1 = typesv1.OCIManifestSchema1
)

type ArtefactInfo struct {
type ImageInfo struct {
io.ReadCloser

MediaType MediaType
Annotations map[string]string
Digest string
}

func (c *Client) SelectArtefacts(ctx context.Context, ref string, mediaTypes ...MediaType) ([]*ArtefactInfo, error) {
imageIndex, indexManifest, image, err := c.IndexOrImage(ctx, ref)
func (c *Client) Fetch(ctx context.Context, ref string, mediaTypes ...MediaType) ([]*ImageInfo, error) {
imageIndex, indexManifest, image, err := c.GetIndexOrImage(ctx, ref)
if err != nil {
return nil, err
}
return c.SelectArtefactsFromIndexOrImage(ctx, imageIndex, indexManifest, image, mediaTypes...)
return c.FetchFromIndexOrImage(ctx, imageIndex, indexManifest, image, mediaTypes...)
}

func (c *Client) SelectArtefactsFromIndexOrImage(ctx context.Context, imageIndex v1.ImageIndex, indexManifest *v1.IndexManifest, image v1.Image, mediaTypes ...MediaType) ([]*ArtefactInfo, error) {
func (c *Client) FetchFromIndexOrImage(ctx context.Context, imageIndex v1.ImageIndex, indexManifest *v1.IndexManifest, image v1.Image, mediaTypes ...MediaType) ([]*ImageInfo, error) {
numMediaTypes := len(mediaTypes)

selector := make(map[MediaType]struct{}, numMediaTypes)
Expand All @@ -77,7 +80,7 @@ func (c *Client) SelectArtefactsFromIndexOrImage(ctx context.Context, imageIndex
return false
}

artefacts := []*ArtefactInfo{}
artefacts := []*ImageInfo{}

if indexManifest == nil {
manifest, err := image.Manifest()
Expand Down Expand Up @@ -112,6 +115,8 @@ func (c *Client) SelectArtefactsFromIndexOrImage(ctx context.Context, imageIndex
return nil, err
}

artefacts = append(artefacts, newManifestDataReader(manifest, manifestDescriptor.Digest))

for j := range manifest.Layers {
layerDescriptor := manifest.Layers[j]

Expand All @@ -130,7 +135,27 @@ func (c *Client) SelectArtefactsFromIndexOrImage(ctx context.Context, imageIndex
return artefacts, nil
}

func (c *Client) GetSingleArtefact(ctx context.Context, ref string) (*ArtefactInfo, error) {
func newManifestDataReader(manifest *v1.Manifest, digest v1.Hash) *ImageInfo {
return &ImageInfo{
ReadCloser: io.NopCloser((*manifestDataReader)(manifest)),
MediaType: OCIManifestSchema1,
Digest: digest.String(),
}
}

type manifestDataReader v1.Manifest

func (m *manifestDataReader) Read(p []byte) (int, error) {
if m == nil {
return 0, io.EOF
}
if err := json.NewEncoder(bytes.NewBuffer(p)).Encode(m); err != nil {
return 0, err
}
return len(p), nil
}

func (c *Client) GetSingleArtefact(ctx context.Context, ref string) (*ImageInfo, error) {
image, layers, err := c.getFlatArtefactLayers(ctx, ref)
if err != nil {
return nil, err
Expand All @@ -141,7 +166,7 @@ func (c *Client) GetSingleArtefact(ctx context.Context, ref string) (*ArtefactIn
return newArtifcatInfoFromLayerDescriptor(image, layers[0])
}

func newArtifcatInfoFromLayerDescriptor(image v1.Image, layerDecriptor v1.Descriptor) (*ArtefactInfo, error) {
func newArtifcatInfoFromLayerDescriptor(image v1.Image, layerDecriptor v1.Descriptor) (*ImageInfo, error) {
layer, err := image.LayerByDigest(layerDecriptor.Digest)
if err != nil {
return nil, fmt.Errorf("fetching artefact image failed: %w", err)
Expand All @@ -151,7 +176,7 @@ func newArtifcatInfoFromLayerDescriptor(image v1.Image, layerDecriptor v1.Descri
if err != nil {
return nil, fmt.Errorf("extracting compressed aretefact image failed: %w", err)
}
info := &ArtefactInfo{
info := &ImageInfo{
ReadCloser: blob,
MediaType: layerDecriptor.MediaType,
Annotations: layerDecriptor.Annotations,
Expand All @@ -161,7 +186,7 @@ func newArtifcatInfoFromLayerDescriptor(image v1.Image, layerDecriptor v1.Descri
}

func (c *Client) getFlatArtefactLayers(ctx context.Context, ref string) (v1.Image, []v1.Descriptor, error) {
imageIndex, indexManifest, image, err := c.IndexOrImage(ctx, ref)
imageIndex, indexManifest, image, err := c.GetIndexOrImage(ctx, ref)
if err != nil {
return nil, nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion oci/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (c *Client) Copy(ctx context.Context, srcRef, dstRef, digest string) error
return nil
}

func (c *Client) IndexOrImage(ctx context.Context, ref string) (v1.ImageIndex, *v1.IndexManifest, v1.Image, error) {
func (c *Client) GetIndexOrImage(ctx context.Context, ref string) (v1.ImageIndex, *v1.IndexManifest, v1.Image, error) {
parsedRef, err := name.ParseReference(ref)
if err != nil {
return nil, nil, nil, fmt.Errorf("invalid URL %q: %w", ref, err)
Expand Down
2 changes: 1 addition & 1 deletion tape/app/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ func (c *TapeImagesCommand) CollectInfo(ctx context.Context, images *types.Image
})
}

artefacts, err := client.SelectArtefactsFromIndexOrImage(ctx, imageIndex, indexManifest, nil, "application/vnd.in-toto+json")
artefacts, err := client.FetchFromIndexOrImage(ctx, imageIndex, indexManifest, nil, "application/vnd.in-toto+json")
if err != nil {
return fmt.Errorf("failed to fetch inline attestation: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion tape/app/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (c *TapePullCommand) Execute(args []string) error {

client := oci.NewClient(nil)

artefacts, err := client.SelectArtefacts(ctx, c.Image, oci.ContentMediaType, oci.AttestMediaType)
artefacts, err := client.Fetch(ctx, c.Image, oci.ContentMediaType, oci.AttestMediaType)
if err != nil {
return err
}
Expand Down

0 comments on commit 7071da6

Please sign in to comment.