123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- package snapshot
- import (
- "context"
- "sync"
- "github.com/containerd/containerd/leases"
- "github.com/containerd/log"
- bolt "go.etcd.io/bbolt"
- )
- type sLM struct {
- manager leases.Manager
- s *snapshotter
- mu sync.Mutex
- byLease map[string]map[string]struct{}
- bySnapshot map[string]map[string]struct{}
- }
- func newLeaseManager(s *snapshotter, lm leases.Manager) *sLM {
- return &sLM{
- s: s,
- manager: lm,
- byLease: map[string]map[string]struct{}{},
- bySnapshot: map[string]map[string]struct{}{},
- }
- }
- func (l *sLM) Create(ctx context.Context, opts ...leases.Opt) (leases.Lease, error) {
- return l.manager.Create(ctx, opts...)
- }
- func (l *sLM) Delete(ctx context.Context, lease leases.Lease, opts ...leases.DeleteOpt) error {
- if err := l.manager.Delete(ctx, lease, opts...); err != nil {
- return err
- }
- l.mu.Lock()
- if snaps, ok := l.byLease[lease.ID]; ok {
- for sID := range snaps {
- l.delRef(lease.ID, sID)
- }
- }
- l.mu.Unlock()
- return nil
- }
- func (l *sLM) List(ctx context.Context, filters ...string) ([]leases.Lease, error) {
- return l.manager.List(ctx, filters...)
- }
- func (l *sLM) AddResource(ctx context.Context, lease leases.Lease, resource leases.Resource) error {
- if err := l.manager.AddResource(ctx, lease, resource); err != nil {
- return err
- }
- if resource.Type == "snapshots/default" {
- l.mu.Lock()
- l.addRef(lease.ID, resource.ID)
- l.mu.Unlock()
- }
- return nil
- }
- func (l *sLM) DeleteResource(ctx context.Context, lease leases.Lease, resource leases.Resource) error {
- if err := l.manager.DeleteResource(ctx, lease, resource); err != nil {
- return err
- }
- if resource.Type == "snapshots/default" {
- l.mu.Lock()
- l.delRef(lease.ID, resource.ID)
- l.mu.Unlock()
- }
- return nil
- }
- func (l *sLM) ListResources(ctx context.Context, lease leases.Lease) ([]leases.Resource, error) {
- return l.manager.ListResources(ctx, lease)
- }
- func (l *sLM) addRef(lID, sID string) {
- load := false
- snapshots, ok := l.byLease[lID]
- if !ok {
- snapshots = map[string]struct{}{}
- l.byLease[lID] = snapshots
- }
- if _, ok := snapshots[sID]; !ok {
- snapshots[sID] = struct{}{}
- }
- leases, ok := l.bySnapshot[sID]
- if !ok {
- leases = map[string]struct{}{}
- l.byLease[sID] = leases
- load = true
- }
- if _, ok := leases[lID]; !ok {
- leases[lID] = struct{}{}
- }
- if load {
- l.s.getLayer(sID, true)
- if _, ok := l.s.chainID(sID); ok {
- l.s.db.Update(func(tx *bolt.Tx) error {
- b, err := tx.CreateBucketIfNotExists([]byte(lID))
- if err != nil {
- return err
- }
- return b.Put(keyChainID, []byte(sID))
- })
- }
- }
- }
- func (l *sLM) delRef(lID, sID string) {
- snapshots, ok := l.byLease[lID]
- if !ok {
- delete(snapshots, sID)
- if len(snapshots) == 0 {
- delete(l.byLease, lID)
- }
- }
- leases, ok := l.bySnapshot[sID]
- if !ok {
- delete(leases, lID)
- if len(leases) == 0 {
- delete(l.bySnapshot, sID)
- if err := l.s.remove(context.TODO(), sID); err != nil {
- log.G(context.TODO()).Warnf("failed to remove snapshot %v", sID)
- }
- }
- }
- }
|