github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/builder/builder-next/adapters/snapshot/leasemanager.go (about) 1 package snapshot 2 3 import ( 4 "context" 5 "sync" 6 7 "github.com/containerd/containerd/leases" 8 "github.com/sirupsen/logrus" 9 ) 10 11 type sLM struct { 12 manager leases.Manager 13 s *snapshotter 14 15 mu sync.Mutex 16 byLease map[string]map[string]struct{} 17 bySnapshot map[string]map[string]struct{} 18 } 19 20 func newLeaseManager(s *snapshotter, lm leases.Manager) *sLM { 21 return &sLM{ 22 s: s, 23 manager: lm, 24 25 byLease: map[string]map[string]struct{}{}, 26 bySnapshot: map[string]map[string]struct{}{}, 27 } 28 } 29 30 func (l *sLM) Create(ctx context.Context, opts ...leases.Opt) (leases.Lease, error) { 31 return l.manager.Create(ctx, opts...) 32 } 33 34 func (l *sLM) Delete(ctx context.Context, lease leases.Lease, opts ...leases.DeleteOpt) error { 35 if err := l.manager.Delete(ctx, lease, opts...); err != nil { 36 return err 37 } 38 l.mu.Lock() 39 if snaps, ok := l.byLease[lease.ID]; ok { 40 for sID := range snaps { 41 l.delRef(lease.ID, sID) 42 } 43 } 44 l.mu.Unlock() 45 return nil 46 } 47 48 func (l *sLM) List(ctx context.Context, filters ...string) ([]leases.Lease, error) { 49 return l.manager.List(ctx, filters...) 50 } 51 52 func (l *sLM) AddResource(ctx context.Context, lease leases.Lease, resource leases.Resource) error { 53 if err := l.manager.AddResource(ctx, lease, resource); err != nil { 54 return err 55 } 56 if resource.Type == "snapshots/default" { 57 l.mu.Lock() 58 l.addRef(lease.ID, resource.ID) 59 l.mu.Unlock() 60 } 61 return nil 62 } 63 64 func (l *sLM) DeleteResource(ctx context.Context, lease leases.Lease, resource leases.Resource) error { 65 if err := l.manager.DeleteResource(ctx, lease, resource); err != nil { 66 return err 67 } 68 if resource.Type == "snapshots/default" { 69 l.mu.Lock() 70 l.delRef(lease.ID, resource.ID) 71 l.mu.Unlock() 72 } 73 return nil 74 } 75 76 func (l *sLM) ListResources(ctx context.Context, lease leases.Lease) ([]leases.Resource, error) { 77 return l.manager.ListResources(ctx, lease) 78 } 79 80 func (l *sLM) addRef(lID, sID string) { 81 load := false 82 snapshots, ok := l.byLease[lID] 83 if !ok { 84 snapshots = map[string]struct{}{} 85 l.byLease[lID] = snapshots 86 } 87 if _, ok := snapshots[sID]; !ok { 88 snapshots[sID] = struct{}{} 89 } 90 leases, ok := l.bySnapshot[sID] 91 if !ok { 92 leases = map[string]struct{}{} 93 l.byLease[sID] = leases 94 load = true 95 } 96 if _, ok := leases[lID]; !ok { 97 leases[lID] = struct{}{} 98 } 99 100 if load { 101 l.s.getLayer(sID, true) 102 } 103 } 104 105 func (l *sLM) delRef(lID, sID string) { 106 snapshots, ok := l.byLease[lID] 107 if !ok { 108 delete(snapshots, sID) 109 if len(snapshots) == 0 { 110 delete(l.byLease, lID) 111 } 112 } 113 leases, ok := l.bySnapshot[sID] 114 if !ok { 115 delete(leases, lID) 116 if len(leases) == 0 { 117 delete(l.bySnapshot, sID) 118 if err := l.s.remove(context.TODO(), sID); err != nil { 119 logrus.Warnf("failed to remove snapshot %v", sID) 120 } 121 } 122 } 123 }