diff --git a/metadata/content.go b/metadata/content.go index 0797345e2..1a9b16af9 100644 --- a/metadata/content.go +++ b/metadata/content.go @@ -184,6 +184,9 @@ func (cs *contentStore) Delete(ctx context.Context, dgst digest.Digest) error { if err := getBlobsBucket(tx, ns).DeleteBucket([]byte(dgst.String())); err != nil { return err } + if err := removeContentLease(ctx, tx, dgst); err != nil { + return err + } // Mark content store as dirty for triggering garbage collection cs.db.dirtyL.Lock() diff --git a/metadata/leases.go b/metadata/leases.go index 006123d45..f61ea00d1 100644 --- a/metadata/leases.go +++ b/metadata/leases.go @@ -155,7 +155,7 @@ func addSnapshotLease(ctx context.Context, tx *bolt.Tx, snapshotter, key string) namespace, ok := namespaces.Namespace(ctx) if !ok { - panic("namespace must already be required") + panic("namespace must already be checked") } bkt := getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectLeases, []byte(lid)) @@ -176,6 +176,26 @@ func addSnapshotLease(ctx context.Context, tx *bolt.Tx, snapshotter, key string) return bkt.Put([]byte(key), nil) } +func removeSnapshotLease(ctx context.Context, tx *bolt.Tx, snapshotter, key string) error { + lid, ok := leases.Lease(ctx) + if !ok { + return nil + } + + namespace, ok := namespaces.Namespace(ctx) + if !ok { + panic("namespace must already be checked") + } + + bkt := getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectLeases, []byte(lid), bucketKeyObjectSnapshots, []byte(snapshotter)) + if bkt == nil { + // Key does not exist so we return nil + return nil + } + + return bkt.Delete([]byte(key)) +} + func addContentLease(ctx context.Context, tx *bolt.Tx, dgst digest.Digest) error { lid, ok := leases.Lease(ctx) if !ok { @@ -199,3 +219,23 @@ func addContentLease(ctx context.Context, tx *bolt.Tx, dgst digest.Digest) error return bkt.Put([]byte(dgst.String()), nil) } + +func removeContentLease(ctx context.Context, tx *bolt.Tx, dgst digest.Digest) error { + lid, ok := leases.Lease(ctx) + if !ok { + return nil + } + + namespace, ok := namespaces.Namespace(ctx) + if !ok { + panic("namespace must already be checked") + } + + bkt := getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectLeases, []byte(lid), bucketKeyObjectContent) + if bkt == nil { + // Key does not exist so we return nil + return nil + } + + return bkt.Delete([]byte(dgst.String())) +} diff --git a/metadata/snapshot.go b/metadata/snapshot.go index 272c2d01a..013258544 100644 --- a/metadata/snapshot.go +++ b/metadata/snapshot.go @@ -288,6 +288,10 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re } return err } + if err := addSnapshotLease(ctx, tx, s.name, key); err != nil { + return err + } + var bparent string if parent != "" { pbkt := bkt.Bucket([]byte(parent)) @@ -326,10 +330,6 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re return err } - if err := addSnapshotLease(ctx, tx, s.name, key); err != nil { - return err - } - // TODO: Consider doing this outside of transaction to lessen // metadata lock time if readonly { @@ -377,6 +377,9 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap } return err } + if err := addSnapshotLease(ctx, tx, s.name, name); err != nil { + return err + } obkt := bkt.Bucket([]byte(key)) if obkt == nil { @@ -425,9 +428,13 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap if err := boltutil.WriteLabels(bbkt, base.Labels); err != nil { return err } + if err := bkt.DeleteBucket([]byte(key)); err != nil { return err } + if err := removeSnapshotLease(ctx, tx, s.name, key); err != nil { + return err + } // TODO: Consider doing this outside of transaction to lessen // metadata lock time @@ -479,6 +486,9 @@ func (s *snapshotter) Remove(ctx context.Context, key string) error { if err := bkt.DeleteBucket([]byte(key)); err != nil { return err } + if err := removeSnapshotLease(ctx, tx, s.name, key); err != nil { + return err + } // Mark snapshotter as dirty for triggering garbage collection s.db.dirtyL.Lock()