Skip to content
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 84 additions & 47 deletions common/pkg/libartifact/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,24 @@ import (

var ErrEmptyArtifactName = errors.New("artifact name cannot be empty")

type EventCallback func(eventType, name, digest string, attrs map[string]string)

const ManifestSchemaVersion = 2

type ArtifactStore struct {
SystemContext *types.SystemContext
storePath string
lock *lockfile.LockFile
eventCallback EventCallback
}

// NewArtifactStore is a constructor for artifact stores. Most artifact dealings depend on this. Store path is
// the filesystem location.
func NewArtifactStore(storePath string, sc *types.SystemContext) (*ArtifactStore, error) {
func NewArtifactStore(storePath string, sc *types.SystemContext, eventCallback EventCallback) (*ArtifactStore, error) {
return NewArtifactStoreWithEventCallback(storePath, sc, nil)
}

func NewArtifactStoreWithEventCallback(storePath string, sc *types.SystemContext, eventCallback EventCallback) (*ArtifactStore, error) {
if storePath == "" {
return nil, errors.New("store path cannot be empty")
}
Expand All @@ -60,6 +67,7 @@ func NewArtifactStore(storePath string, sc *types.SystemContext) (*ArtifactStore
artifactStore := &ArtifactStore{
storePath: storePath,
SystemContext: sc,
eventCallback: eventCallback,
}

// if the storage dir does not exist, we need to create it.
Expand Down Expand Up @@ -113,7 +121,13 @@ func (as ArtifactStore) Remove(ctx context.Context, name string) (*digest.Digest
if err != nil {
return nil, err
}
return artifactDigest, ir.DeleteImage(ctx, as.SystemContext)
if err := ir.DeleteImage(ctx, as.SystemContext); err != nil {
return artifactDigest, err
}
if as.eventCallback != nil {
as.eventCallback("remove", name, artifactDigest.String(), nil)
}
return artifactDigest, nil
}

// Inspect an artifact in a local store.
Expand Down Expand Up @@ -170,7 +184,11 @@ func (as ArtifactStore) Pull(ctx context.Context, name string, opts libimage.Cop
if err != nil {
return "", err
}
return digest.FromBytes(artifactBytes), nil
artifactDigest := digest.FromBytes(artifactBytes)
if as.eventCallback != nil {
as.eventCallback("pull", name, artifactDigest.String(), nil)
}
return artifactDigest, nil
}

// Push an artifact to an image registry.
Expand Down Expand Up @@ -204,6 +222,9 @@ func (as ArtifactStore) Push(ctx context.Context, src, dest string, opts libimag
return "", err
}
artifactDigest := digest.FromBytes(artifactBytes)
if as.eventCallback != nil {
as.eventCallback("push", src, artifactDigest.String(), nil)
}
return artifactDigest, nil
}

Expand Down Expand Up @@ -400,6 +421,11 @@ func (as ArtifactStore) Add(ctx context.Context, dest string, artifactBlobs []li
}
}
}
if as.eventCallback != nil {
as.eventCallback("add", dest, artifactManifestDigest.String(), map[string]string{
"files": fmt.Sprintf("%d", len(artifactBlobs)),
})
}
return &artifactManifestDigest, nil
}

Expand Down Expand Up @@ -525,10 +551,10 @@ func (as ArtifactStore) Extract(ctx context.Context, nameOrDigest string, target
digest = arty.Manifest.Layers[0].Digest
}

return copyTrustedImageBlobToFile(ctx, imgSrc, digest, target)
}

if len(options.Digest) > 0 || len(options.Title) > 0 {
if err := copyTrustedImageBlobToFile(ctx, imgSrc, digest, target); err != nil {
return err
}
} else if len(options.Digest) > 0 || len(options.Title) > 0 {
digest, err := findDigest(arty, &options.FilterBlobOptions)
if err != nil {
return err
Expand All @@ -542,22 +568,29 @@ func (as ArtifactStore) Extract(ctx context.Context, nameOrDigest string, target
return err
}

return copyTrustedImageBlobToFile(ctx, imgSrc, digest, filepath.Join(target, filename))
}

for _, l := range arty.Manifest.Layers {
title := l.Annotations[specV1.AnnotationTitle]
filename, err := generateArtifactBlobName(title, l.Digest)
if err != nil {
if err := copyTrustedImageBlobToFile(ctx, imgSrc, digest, filepath.Join(target, filename)); err != nil {
return err
}
} else {
for _, l := range arty.Manifest.Layers {
title := l.Annotations[specV1.AnnotationTitle]
filename, err := generateArtifactBlobName(title, l.Digest)
if err != nil {
return err
}

err = copyTrustedImageBlobToFile(ctx, imgSrc, l.Digest, filepath.Join(target, filename))
if err != nil {
return err
err = copyTrustedImageBlobToFile(ctx, imgSrc, l.Digest, filepath.Join(target, filename))
if err != nil {
return err
}
}
}

if as.eventCallback != nil {
attrs := map[string]string{"target": target}
as.eventCallback("extract", arty.Name, options.Digest, attrs)
}

return nil
}

Expand Down Expand Up @@ -599,47 +632,51 @@ func (as ArtifactStore) ExtractTarStream(ctx context.Context, w io.Writer, nameO
if err != nil {
return err
}
} else {

return nil
}
artifactBlobCount := len(arty.Manifest.Layers)

artifactBlobCount := len(arty.Manifest.Layers)
type blob struct {
name string
digest digest.Digest
}
blobs := make([]blob, 0, artifactBlobCount)

type blob struct {
name string
digest digest.Digest
}
blobs := make([]blob, 0, artifactBlobCount)
// Gather blob details and return error on any illegal names
for _, l := range arty.Manifest.Layers {
title := l.Annotations[specV1.AnnotationTitle]
digest := l.Digest
var name string

// Gather blob details and return error on any illegal names
for _, l := range arty.Manifest.Layers {
title := l.Annotations[specV1.AnnotationTitle]
digest := l.Digest
var name string
if artifactBlobCount != 1 || !options.ExcludeTitle {
name, err = generateArtifactBlobName(title, digest)
if err != nil {
return err
}
}

blobs = append(blobs, blob{
name: name,
digest: digest,
})
}

// Wrap io.Writer in a tar.Writer
tw := tar.NewWriter(w)
defer tw.Close()

if artifactBlobCount != 1 || !options.ExcludeTitle {
name, err = generateArtifactBlobName(title, digest)
// Write each blob to tar.Writer then close
for _, b := range blobs {
err := copyTrustedImageBlobToTarStream(ctx, imgSrc, b.digest, b.name, tw)
if err != nil {
return err
}
}

blobs = append(blobs, blob{
name: name,
digest: digest,
})
}

// Wrap io.Writer in a tar.Writer
tw := tar.NewWriter(w)
defer tw.Close()

// Write each blob to tar.Writer then close
for _, b := range blobs {
err := copyTrustedImageBlobToTarStream(ctx, imgSrc, b.digest, b.name, tw)
if err != nil {
return err
}
if as.eventCallback != nil {
attrs := map[string]string{"format": "tar-stream"}
as.eventCallback("extract", arty.Name, options.Digest, attrs)
}

return nil
Expand Down
Loading