Merge pull request #1 from waynr/add-vacuum-removelayerlink-func

Add Vacuum.RemoveLayerLink function
This commit is contained in:
wayne 2020-09-03 09:05:16 -05:00 committed by GitHub
commit 0e6ff0e95e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 6 deletions

View File

@ -5,6 +5,7 @@ import (
"fmt"
"github.com/docker/distribution"
"github.com/docker/distribution/manifest/schema2"
"github.com/docker/distribution/reference"
"github.com/docker/distribution/registry/storage/driver"
"github.com/opencontainers/go-digest"
@ -25,6 +26,7 @@ type ManifestDel struct {
Name string
Digest digest.Digest
Tags []string
Layers []digest.Digest
}
// MarkAndSweep performs a mark and sweep of registry data
@ -61,6 +63,11 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
}
err = manifestEnumerator.Enumerate(ctx, func(dgst digest.Digest) error {
manifest, err := manifestService.Get(ctx, dgst)
if err != nil {
return fmt.Errorf("failed to retrieve manifest for digest %v: %v", dgst, err)
}
if opts.RemoveUntagged {
// fetch all tags where this manifest is the latest one
tags, err := repository.Tags(ctx).Lookup(ctx, distribution.Descriptor{Digest: dgst})
@ -76,7 +83,23 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
if err != nil {
return fmt.Errorf("failed to retrieve tags %v", err)
}
manifestArr = append(manifestArr, ManifestDel{Name: repoName, Digest: dgst, Tags: allTags})
manifestDel := ManifestDel{
Name: repoName,
Digest: dgst,
Tags: allTags,
Layers: []digest.Digest{},
}
for _, ref := range manifest.References() {
if ref.MediaType == schema2.MediaTypeLayer ||
ref.MediaType == schema2.MediaTypeImageConfig {
manifestDel.Layers = append(manifestDel.Layers, ref.Digest)
}
}
manifestArr = append(manifestArr, manifestDel)
return nil
}
}
@ -84,11 +107,6 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
emit("%s: marking manifest %s ", repoName, dgst)
markSet[dgst] = struct{}{}
manifest, err := manifestService.Get(ctx, dgst)
if err != nil {
return fmt.Errorf("failed to retrieve manifest for digest %v: %v", dgst, err)
}
descriptors := manifest.References()
for _, descriptor := range descriptors {
markSet[descriptor.Digest] = struct{}{}
@ -122,6 +140,14 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
if err != nil {
return fmt.Errorf("failed to delete manifest %s: %v", obj.Digest, err)
}
for _, layerDgst := range obj.Layers {
if _, ok := markSet[layerDgst]; !ok {
err := vacuum.RemoveLayerLink(obj.Name, layerDgst)
if err != nil {
return fmt.Errorf("failed to delete layer link %s for manifest %s: %v", layerDgst, obj.Name, err)
}
}
}
}
}
blobService := registry.Blobs()

View File

@ -84,6 +84,28 @@ func (v Vacuum) RemoveManifest(name string, dgst digest.Digest, tags []string) e
return v.driver.Delete(v.ctx, manifestPath)
}
// RemoveLayerLink removes a layer link from the filesystem
func (v Vacuum) RemoveLayerLink(manifestName string, dgst digest.Digest) error {
layerLinkPath, err := pathFor(layerLinkPathSpec{name: manifestName, digest: dgst})
if err != nil {
return err
}
dcontext.GetLogger(v.ctx).Infof("Deleting layer link path : %s", layerLinkPath)
_, err = v.driver.Stat(v.ctx, layerLinkPath)
if err != nil {
switch err := err.(type) {
case driver.PathNotFoundError:
return nil
default:
return err
}
}
return v.driver.Delete(v.ctx, layerLinkPath)
}
// RemoveRepository removes a repository directory from the
// filesystem
func (v Vacuum) RemoveRepository(repoName string) error {