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  }