mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
a430bc5d5f
After switch to leases all ref IDs use generated IDs meaning that EnsureLayer hack needs to save the chainID for pulled layers. Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
133 lines
2.9 KiB
Go
133 lines
2.9 KiB
Go
package snapshot
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
|
|
"github.com/containerd/containerd/leases"
|
|
"github.com/sirupsen/logrus"
|
|
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 {
|
|
logrus.Warnf("failed to remove snapshot %v", sID)
|
|
}
|
|
}
|
|
}
|
|
}
|