github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/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  	bolt "go.etcd.io/bbolt"
    10  )
    11  
    12  type sLM struct {
    13  	manager leases.Manager
    14  	s       *snapshotter
    15  
    16  	mu         sync.Mutex
    17  	byLease    map[string]map[string]struct{}
    18  	bySnapshot map[string]map[string]struct{}
    19  }
    20  
    21  func newLeaseManager(s *snapshotter, lm leases.Manager) *sLM {
    22  	return &sLM{
    23  		s:       s,
    24  		manager: lm,
    25  
    26  		byLease:    map[string]map[string]struct{}{},
    27  		bySnapshot: map[string]map[string]struct{}{},
    28  	}
    29  }
    30  
    31  func (l *sLM) Create(ctx context.Context, opts ...leases.Opt) (leases.Lease, error) {
    32  	return l.manager.Create(ctx, opts...)
    33  }
    34  
    35  func (l *sLM) Delete(ctx context.Context, lease leases.Lease, opts ...leases.DeleteOpt) error {
    36  	if err := l.manager.Delete(ctx, lease, opts...); err != nil {
    37  		return err
    38  	}
    39  	l.mu.Lock()
    40  	if snaps, ok := l.byLease[lease.ID]; ok {
    41  		for sID := range snaps {
    42  			l.delRef(lease.ID, sID)
    43  		}
    44  	}
    45  	l.mu.Unlock()
    46  	return nil
    47  }
    48  
    49  func (l *sLM) List(ctx context.Context, filters ...string) ([]leases.Lease, error) {
    50  	return l.manager.List(ctx, filters...)
    51  }
    52  
    53  func (l *sLM) AddResource(ctx context.Context, lease leases.Lease, resource leases.Resource) error {
    54  	if err := l.manager.AddResource(ctx, lease, resource); err != nil {
    55  		return err
    56  	}
    57  	if resource.Type == "snapshots/default" {
    58  		l.mu.Lock()
    59  		l.addRef(lease.ID, resource.ID)
    60  		l.mu.Unlock()
    61  	}
    62  	return nil
    63  }
    64  
    65  func (l *sLM) DeleteResource(ctx context.Context, lease leases.Lease, resource leases.Resource) error {
    66  	if err := l.manager.DeleteResource(ctx, lease, resource); err != nil {
    67  		return err
    68  	}
    69  	if resource.Type == "snapshots/default" {
    70  		l.mu.Lock()
    71  		l.delRef(lease.ID, resource.ID)
    72  		l.mu.Unlock()
    73  	}
    74  	return nil
    75  }
    76  
    77  func (l *sLM) ListResources(ctx context.Context, lease leases.Lease) ([]leases.Resource, error) {
    78  	return l.manager.ListResources(ctx, lease)
    79  }
    80  
    81  func (l *sLM) addRef(lID, sID string) {
    82  	load := false
    83  	snapshots, ok := l.byLease[lID]
    84  	if !ok {
    85  		snapshots = map[string]struct{}{}
    86  		l.byLease[lID] = snapshots
    87  	}
    88  	if _, ok := snapshots[sID]; !ok {
    89  		snapshots[sID] = struct{}{}
    90  	}
    91  	leases, ok := l.bySnapshot[sID]
    92  	if !ok {
    93  		leases = map[string]struct{}{}
    94  		l.byLease[sID] = leases
    95  		load = true
    96  	}
    97  	if _, ok := leases[lID]; !ok {
    98  		leases[lID] = struct{}{}
    99  	}
   100  
   101  	if load {
   102  		l.s.getLayer(sID, true)
   103  		if _, ok := l.s.chainID(sID); ok {
   104  			l.s.db.Update(func(tx *bolt.Tx) error {
   105  				b, err := tx.CreateBucketIfNotExists([]byte(lID))
   106  				if err != nil {
   107  					return err
   108  				}
   109  				return b.Put(keyChainID, []byte(sID))
   110  			})
   111  		}
   112  	}
   113  }
   114  
   115  func (l *sLM) delRef(lID, sID string) {
   116  	snapshots, ok := l.byLease[lID]
   117  	if !ok {
   118  		delete(snapshots, sID)
   119  		if len(snapshots) == 0 {
   120  			delete(l.byLease, lID)
   121  		}
   122  	}
   123  	leases, ok := l.bySnapshot[sID]
   124  	if !ok {
   125  		delete(leases, lID)
   126  		if len(leases) == 0 {
   127  			delete(l.bySnapshot, sID)
   128  			if err := l.s.remove(context.TODO(), sID); err != nil {
   129  				logrus.Warnf("failed to remove snapshot %v", sID)
   130  			}
   131  		}
   132  	}
   133  }