mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
124 lines
2.7 KiB
Go
124 lines
2.7 KiB
Go
|
package snapshot
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"sync"
|
||
|
|
||
|
"github.com/containerd/containerd/leases"
|
||
|
"github.com/sirupsen/logrus"
|
||
|
)
|
||
|
|
||
|
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)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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 {
|
||
|
logrus.Warnf("failed to remove snapshot %v", sID)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|