Преглед на файлове

Merge pull request #45963 from rumpl/c8d-image-save-lease

c8d: Make sure the content isn't removed while we export
Sebastiaan van Stijn преди 2 години
родител
ревизия
9ba41b791e
променени са 1 файла, в които са добавени 38 реда и са изтрити 2 реда
  1. 38 2
      daemon/containerd/image_exporter.go

+ 38 - 2
daemon/containerd/image_exporter.go

@@ -6,9 +6,11 @@ import (
 	"io"
 	"io"
 
 
 	"github.com/containerd/containerd"
 	"github.com/containerd/containerd"
+	"github.com/containerd/containerd/content"
 	cerrdefs "github.com/containerd/containerd/errdefs"
 	cerrdefs "github.com/containerd/containerd/errdefs"
 	containerdimages "github.com/containerd/containerd/images"
 	containerdimages "github.com/containerd/containerd/images"
 	"github.com/containerd/containerd/images/archive"
 	"github.com/containerd/containerd/images/archive"
+	"github.com/containerd/containerd/leases"
 	"github.com/containerd/containerd/log"
 	"github.com/containerd/containerd/log"
 	"github.com/containerd/containerd/mount"
 	"github.com/containerd/containerd/mount"
 	cplatforms "github.com/containerd/containerd/platforms"
 	cplatforms "github.com/containerd/containerd/platforms"
@@ -58,11 +60,17 @@ func (i *ImageService) ExportImage(ctx context.Context, names []string, outStrea
 		archive.WithPlatform(platform),
 		archive.WithPlatform(platform),
 	}
 	}
 
 
-	ctx, release, err := i.client.WithLease(ctx)
+	contentStore := i.client.ContentStore()
+	leasesManager := i.client.LeasesService()
+	lease, err := leasesManager.Create(ctx, leases.WithRandomID())
 	if err != nil {
 	if err != nil {
 		return errdefs.System(err)
 		return errdefs.System(err)
 	}
 	}
-	defer release(ctx)
+	defer func() {
+		if err := leasesManager.Delete(ctx, lease); err != nil {
+			log.G(ctx).WithError(err).Warn("cleaning up lease")
+		}
+	}()
 
 
 	for _, name := range names {
 	for _, name := range names {
 		target, err := i.resolveDescriptor(ctx, name)
 		target, err := i.resolveDescriptor(ctx, name)
@@ -70,6 +78,10 @@ func (i *ImageService) ExportImage(ctx context.Context, names []string, outStrea
 			return err
 			return err
 		}
 		}
 
 
+		if err = leaseContent(ctx, contentStore, leasesManager, lease, target); err != nil {
+			return err
+		}
+
 		// We may not have locally all the platforms that are specified in the index.
 		// We may not have locally all the platforms that are specified in the index.
 		// Export only those manifests that we have.
 		// Export only those manifests that we have.
 		// TODO(vvoland): Reconsider this when `--platform` is added.
 		// TODO(vvoland): Reconsider this when `--platform` is added.
@@ -101,6 +113,30 @@ func (i *ImageService) ExportImage(ctx context.Context, names []string, outStrea
 	return i.client.Export(ctx, outStream, opts...)
 	return i.client.Export(ctx, outStream, opts...)
 }
 }
 
 
+// leaseContent will add a resource to the lease for each child of the descriptor making sure that it and
+// its children won't be deleted while the lease exists
+func leaseContent(ctx context.Context, store content.Store, leasesManager leases.Manager, lease leases.Lease, desc ocispec.Descriptor) error {
+	return containerdimages.Walk(ctx, containerdimages.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
+		_, err := store.Info(ctx, desc.Digest)
+		if err != nil {
+			if errors.Is(err, cerrdefs.ErrNotFound) {
+				return nil, nil
+			}
+			return nil, errdefs.System(err)
+		}
+
+		r := leases.Resource{
+			ID:   desc.Digest.String(),
+			Type: "content",
+		}
+		if err := leasesManager.AddResource(ctx, lease, r); err != nil {
+			return nil, errdefs.System(err)
+		}
+
+		return containerdimages.Children(ctx, store, desc)
+	}), desc)
+}
+
 // LoadImage uploads a set of images into the repository. This is the
 // LoadImage uploads a set of images into the repository. This is the
 // complement of ExportImage.  The input stream is an uncompressed tar
 // complement of ExportImage.  The input stream is an uncompressed tar
 // ball containing images and metadata.
 // ball containing images and metadata.