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" "fmt"
"github.com/docker/distribution" "github.com/docker/distribution"
"github.com/docker/distribution/manifest/schema2"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/docker/distribution/registry/storage/driver" "github.com/docker/distribution/registry/storage/driver"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
@ -25,6 +26,7 @@ type ManifestDel struct {
Name string Name string
Digest digest.Digest Digest digest.Digest
Tags []string Tags []string
Layers []digest.Digest
} }
// MarkAndSweep performs a mark and sweep of registry data // 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 { 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 { if opts.RemoveUntagged {
// fetch all tags where this manifest is the latest one // fetch all tags where this manifest is the latest one
tags, err := repository.Tags(ctx).Lookup(ctx, distribution.Descriptor{Digest: dgst}) 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 { if err != nil {
return fmt.Errorf("failed to retrieve tags %v", err) 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 return nil
} }
} }
@ -84,11 +107,6 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
emit("%s: marking manifest %s ", repoName, dgst) emit("%s: marking manifest %s ", repoName, dgst)
markSet[dgst] = struct{}{} 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() descriptors := manifest.References()
for _, descriptor := range descriptors { for _, descriptor := range descriptors {
markSet[descriptor.Digest] = struct{}{} markSet[descriptor.Digest] = struct{}{}
@ -122,6 +140,14 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
if err != nil { if err != nil {
return fmt.Errorf("failed to delete manifest %s: %v", obj.Digest, err) 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() 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) 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 // RemoveRepository removes a repository directory from the
// filesystem // filesystem
func (v Vacuum) RemoveRepository(repoName string) error { func (v Vacuum) RemoveRepository(repoName string) error {