snapshot: clean up snapshot interface

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
docker-18.09
Tonis Tiigi 2017-12-27 23:07:13 -08:00
parent 56353f99a8
commit b0679c66db
15 changed files with 111 additions and 111 deletions

14
cache/blobs/blobs.go vendored
View File

@ -1,7 +1,6 @@
package blobs package blobs
import ( import (
gocontext "context"
"time" "time"
"github.com/containerd/containerd/content" "github.com/containerd/containerd/content"
@ -26,19 +25,10 @@ type DiffPair struct {
Blobsum digest.Digest Blobsum digest.Digest
} }
type blobmapper interface {
GetBlob(ctx gocontext.Context, key string) (digest.Digest, digest.Digest, error)
SetBlob(ctx gocontext.Context, key string, diffID, blob digest.Digest) error
}
func GetDiffPairs(ctx context.Context, contentStore content.Store, snapshotter snapshot.Snapshotter, differ diff.Differ, ref cache.ImmutableRef) ([]DiffPair, error) { func GetDiffPairs(ctx context.Context, contentStore content.Store, snapshotter snapshot.Snapshotter, differ diff.Differ, ref cache.ImmutableRef) ([]DiffPair, error) {
if ref == nil { if ref == nil {
return nil, nil return nil, nil
} }
blobmap, ok := snapshotter.(blobmapper)
if !ok {
return nil, errors.Errorf("image exporter requires snapshotter with blobs mapping support")
}
eg, ctx := errgroup.WithContext(ctx) eg, ctx := errgroup.WithContext(ctx)
var diffPairs []DiffPair var diffPairs []DiffPair
@ -57,7 +47,7 @@ func GetDiffPairs(ctx context.Context, contentStore content.Store, snapshotter s
} }
eg.Go(func() error { eg.Go(func() error {
dp, err := g.Do(ctx, ref.ID(), func(ctx context.Context) (interface{}, error) { dp, err := g.Do(ctx, ref.ID(), func(ctx context.Context) (interface{}, error) {
diffID, blob, err := blobmap.GetBlob(ctx, ref.ID()) diffID, blob, err := snapshotter.GetBlob(ctx, ref.ID())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -100,7 +90,7 @@ func GetDiffPairs(ctx context.Context, contentStore content.Store, snapshotter s
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := blobmap.SetBlob(ctx, ref.ID(), diffIDDigest, descr.Digest); err != nil { if err := snapshotter.SetBlob(ctx, ref.ID(), diffIDDigest, descr.Digest); err != nil {
return nil, err return nil, err
} }
return DiffPair{DiffID: diffIDDigest, Blobsum: descr.Digest}, nil return DiffPair{DiffID: diffIDDigest, Blobsum: descr.Digest}, nil

View File

@ -2,7 +2,6 @@ package cacheimport
import ( import (
"bytes" "bytes"
gocontext "context"
"encoding/json" "encoding/json"
"time" "time"
@ -25,11 +24,6 @@ import (
const mediaTypeConfig = "application/vnd.buildkit.cacheconfig.v0" const mediaTypeConfig = "application/vnd.buildkit.cacheconfig.v0"
type blobmapper interface {
GetBlob(ctx gocontext.Context, key string) (digest.Digest, digest.Digest, error)
SetBlob(ctx gocontext.Context, key string, diffID, blob digest.Digest) error
}
type CacheRecord struct { type CacheRecord struct {
CacheKey digest.Digest CacheKey digest.Digest
Reference cache.ImmutableRef Reference cache.ImmutableRef

View File

@ -269,7 +269,6 @@ func (ii *importInfo) unpack(ctx context.Context, dpairs []blobs.DiffPair) (stri
var chain []digest.Digest var chain []digest.Digest
for _, layer := range layers { for _, layer := range layers {
labels := map[string]string{ labels := map[string]string{
"containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339Nano),
"containerd.io/uncompressed": layer.Diff.Digest.String(), "containerd.io/uncompressed": layer.Diff.Digest.String(),
} }
if _, err := rootfs.ApplyLayer(ctx, layer, chain, ii.opt.Snapshotter, ii.opt.Applier, cdsnapshot.WithLabels(labels)); err != nil { if _, err := rootfs.ApplyLayer(ctx, layer, chain, ii.opt.Snapshotter, ii.opt.Applier, cdsnapshot.WithLabels(labels)); err != nil {
@ -291,7 +290,7 @@ func (ii *importInfo) fillBlobMapping(ctx context.Context, layers []rootfs.Layer
for _, l := range layers { for _, l := range layers {
chain = append(chain, l.Diff.Digest) chain = append(chain, l.Diff.Digest)
chainID := identity.ChainID(chain) chainID := identity.ChainID(chain)
if err := ii.opt.Snapshotter.(blobmapper).SetBlob(ctx, string(chainID), l.Diff.Digest, l.Blob.Digest); err != nil { if err := ii.opt.Snapshotter.SetBlob(ctx, string(chainID), l.Diff.Digest, l.Blob.Digest); err != nil {
return err return err
} }
} }

View File

@ -11,6 +11,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/containerd/containerd/snapshots"
"github.com/containerd/containerd/snapshots/naive" "github.com/containerd/containerd/snapshots/naive"
"github.com/moby/buildkit/cache" "github.com/moby/buildkit/cache"
"github.com/moby/buildkit/cache/metadata" "github.com/moby/buildkit/cache/metadata"
@ -383,7 +384,7 @@ func createRef(t *testing.T, cm cache.Manager, files []string) cache.ImmutableRe
return ref return ref
} }
func setupCacheManager(t *testing.T, tmpdir string, snapshotter snapshot.Snapshotter) cache.Manager { func setupCacheManager(t *testing.T, tmpdir string, snapshotter snapshots.Snapshotter) cache.Manager {
md, err := metadata.NewStore(filepath.Join(tmpdir, "metadata.db")) md, err := metadata.NewStore(filepath.Join(tmpdir, "metadata.db"))
require.NoError(t, err) require.NoError(t, err)

18
cache/manager.go vendored
View File

@ -6,11 +6,10 @@ import (
"sync" "sync"
"time" "time"
cdsnapshot "github.com/containerd/containerd/snapshots" "github.com/containerd/containerd/snapshots"
"github.com/moby/buildkit/cache/metadata" "github.com/moby/buildkit/cache/metadata"
"github.com/moby/buildkit/client" "github.com/moby/buildkit/client"
"github.com/moby/buildkit/identity" "github.com/moby/buildkit/identity"
"github.com/moby/buildkit/snapshot"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
@ -23,7 +22,7 @@ var (
) )
type ManagerOpt struct { type ManagerOpt struct {
Snapshotter snapshot.Snapshotter Snapshotter snapshots.Snapshotter
GCPolicy GCPolicy GCPolicy GCPolicy
MetadataStore *metadata.Store MetadataStore *metadata.Store
} }
@ -175,7 +174,7 @@ func (cm *cacheManager) getRecord(ctx context.Context, id string, opts ...RefOpt
rec := &cacheRecord{ rec := &cacheRecord{
mu: &sync.Mutex{}, mu: &sync.Mutex{},
mutable: info.Kind != cdsnapshot.KindCommitted, mutable: info.Kind != snapshots.KindCommitted,
cm: cm, cm: cm,
refs: make(map[Mountable]struct{}), refs: make(map[Mountable]struct{}),
parent: parent, parent: parent,
@ -218,10 +217,7 @@ func (cm *cacheManager) New(ctx context.Context, s ImmutableRef, opts ...RefOpti
parentID = parent.ID() parentID = parent.ID()
} }
labels := map[string]string{ if _, err := cm.Snapshotter.Prepare(ctx, id, parentID); err != nil {
"containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339Nano),
}
if _, err := cm.Snapshotter.Prepare(ctx, id, parentID, cdsnapshot.WithLabels(labels)); err != nil {
if parent != nil { if parent != nil {
parent.Release(context.TODO()) parent.Release(context.TODO())
} }
@ -294,12 +290,18 @@ func (cm *cacheManager) Prune(ctx context.Context, ch chan client.UsageInfo) err
for _, cr := range cm.records { for _, cr := range cm.records {
cr.mu.Lock() cr.mu.Lock()
// ignore duplicates that share data // ignore duplicates that share data
if cr.equalImmutable != nil && len(cr.equalImmutable.refs) > 0 || cr.equalMutable != nil && len(cr.refs) == 0 { if cr.equalImmutable != nil && len(cr.equalImmutable.refs) > 0 || cr.equalMutable != nil && len(cr.refs) == 0 {
cr.mu.Unlock() cr.mu.Unlock()
continue continue
} }
if cr.isDead() {
cr.mu.Unlock()
continue
}
if len(cr.refs) == 0 { if len(cr.refs) == 0 {
cr.dead = true cr.dead = true
toDelete = append(toDelete, cr) toDelete = append(toDelete, cr)

View File

@ -9,6 +9,7 @@ import (
"testing" "testing"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/snapshots"
"github.com/containerd/containerd/snapshots/naive" "github.com/containerd/containerd/snapshots/naive"
"github.com/moby/buildkit/cache/metadata" "github.com/moby/buildkit/cache/metadata"
"github.com/moby/buildkit/client" "github.com/moby/buildkit/client"
@ -368,7 +369,7 @@ func TestLazyCommit(t *testing.T) {
require.Equal(t, errNotFound, errors.Cause(err)) require.Equal(t, errNotFound, errors.Cause(err))
} }
func getCacheManager(t *testing.T, tmpdir string, snapshotter snapshot.Snapshotter) Manager { func getCacheManager(t *testing.T, tmpdir string, snapshotter snapshots.Snapshotter) Manager {
md, err := metadata.NewStore(filepath.Join(tmpdir, "metadata.db")) md, err := metadata.NewStore(filepath.Join(tmpdir, "metadata.db"))
require.NoError(t, err) require.NoError(t, err)

12
cache/refs.go vendored
View File

@ -2,10 +2,8 @@ package cache
import ( import (
"sync" "sync"
"time"
"github.com/containerd/containerd/mount" "github.com/containerd/containerd/mount"
cdsnapshot "github.com/containerd/containerd/snapshots"
"github.com/moby/buildkit/cache/metadata" "github.com/moby/buildkit/cache/metadata"
"github.com/moby/buildkit/identity" "github.com/moby/buildkit/identity"
"github.com/moby/buildkit/util/flightcontrol" "github.com/moby/buildkit/util/flightcontrol"
@ -150,10 +148,7 @@ func (cr *cacheRecord) Mount(ctx context.Context, readonly bool) ([]mount.Mount,
} }
if cr.viewMount == nil { // TODO: handle this better if cr.viewMount == nil { // TODO: handle this better
cr.view = identity.NewID() cr.view = identity.NewID()
labels := map[string]string{ m, err := cr.cm.Snapshotter.View(ctx, cr.view, cr.ID())
"containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339Nano),
}
m, err := cr.cm.Snapshotter.View(ctx, cr.view, cr.ID(), cdsnapshot.WithLabels(labels))
if err != nil { if err != nil {
cr.view = "" cr.view = ""
return nil, errors.Wrapf(err, "failed to mount %s", cr.ID()) return nil, errors.Wrapf(err, "failed to mount %s", cr.ID())
@ -243,10 +238,7 @@ func (cr *cacheRecord) finalize(ctx context.Context) error {
if mutable == nil { if mutable == nil {
return nil return nil
} }
labels := map[string]string{ err := cr.cm.Snapshotter.Commit(ctx, cr.ID(), mutable.ID())
"containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339Nano),
}
err := cr.cm.Snapshotter.Commit(ctx, cr.ID(), mutable.ID(), cdsnapshot.WithLabels(labels))
if err != nil { if err != nil {
return errors.Wrapf(err, "failed to commit %s", mutable.ID()) return errors.Wrapf(err, "failed to commit %s", mutable.ID())
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/containerd/containerd/content" "github.com/containerd/containerd/content"
"github.com/containerd/containerd/snapshots" "github.com/containerd/containerd/snapshots"
"github.com/moby/buildkit/cache/metadata" "github.com/moby/buildkit/cache/metadata"
"github.com/moby/buildkit/snapshot"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -36,13 +37,13 @@ type Snapshotter struct {
opt Opt opt Opt
} }
func NewSnapshotter(opt Opt) (*Snapshotter, error) { func NewSnapshotter(opt Opt) snapshot.Snapshotter {
s := &Snapshotter{ s := &Snapshotter{
Snapshotter: opt.Snapshotter, Snapshotter: opt.Snapshotter,
opt: opt, opt: opt,
} }
return s, nil return s
} }
// Remove also removes a reference to a blob. If it is a last reference then it deletes it the blob as well // Remove also removes a reference to a blob. If it is a last reference then it deletes it the blob as well
@ -64,7 +65,7 @@ func (s *Snapshotter) Remove(ctx context.Context, key string) error {
if len(blobs) == 1 && blobs[0].ID() == key { // last snapshot if len(blobs) == 1 && blobs[0].ID() == key { // last snapshot
if err := s.opt.Content.Delete(ctx, blob); err != nil { if err := s.opt.Content.Delete(ctx, blob); err != nil {
logrus.Errorf("failed to delete blob %v", blob) logrus.Errorf("failed to delete blob %v: %+v", blob, err)
} }
} }
return nil return nil

View File

@ -1,4 +1,4 @@
package nogc package containerd
import ( import (
"context" "context"

View File

@ -1,15 +1,24 @@
package nogc package containerd
import ( import (
"context" "context"
"time"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/mount" "github.com/containerd/containerd/mount"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
ctdsnapshot "github.com/containerd/containerd/snapshots" ctdsnapshot "github.com/containerd/containerd/snapshots"
"github.com/moby/buildkit/cache/metadata"
"github.com/moby/buildkit/snapshot"
"github.com/moby/buildkit/snapshot/blobmapping"
) )
func NewSnapshotter(snapshotter ctdsnapshot.Snapshotter, ns string, gc func(context.Context) error) ctdsnapshot.Snapshotter { func NewSnapshotter(snapshotter ctdsnapshot.Snapshotter, store content.Store, mdstore *metadata.Store, ns string, gc func(context.Context) error) snapshot.Snapshotter {
return &nsSnapshotter{ns, snapshotter, gc} return blobmapping.NewSnapshotter(blobmapping.Opt{
Content: store,
Snapshotter: &nsSnapshotter{ns, snapshotter, gc},
MetadataStore: mdstore,
})
} }
type nsSnapshotter struct { type nsSnapshotter struct {
@ -38,15 +47,15 @@ func (s *nsSnapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount,
} }
func (s *nsSnapshotter) Prepare(ctx context.Context, key, parent string, opts ...ctdsnapshot.Opt) ([]mount.Mount, error) { func (s *nsSnapshotter) Prepare(ctx context.Context, key, parent string, opts ...ctdsnapshot.Opt) ([]mount.Mount, error) {
ctx = namespaces.WithNamespace(ctx, s.ns) ctx = namespaces.WithNamespace(ctx, s.ns)
return s.Snapshotter.Prepare(ctx, key, parent, opts...) return s.Snapshotter.Prepare(ctx, key, parent, addRootLabel(opts...))
} }
func (s *nsSnapshotter) View(ctx context.Context, key, parent string, opts ...ctdsnapshot.Opt) ([]mount.Mount, error) { func (s *nsSnapshotter) View(ctx context.Context, key, parent string, opts ...ctdsnapshot.Opt) ([]mount.Mount, error) {
ctx = namespaces.WithNamespace(ctx, s.ns) ctx = namespaces.WithNamespace(ctx, s.ns)
return s.Snapshotter.View(ctx, key, parent, opts...) return s.Snapshotter.View(ctx, key, parent, addRootLabel(opts...))
} }
func (s *nsSnapshotter) Commit(ctx context.Context, name, key string, opts ...ctdsnapshot.Opt) error { func (s *nsSnapshotter) Commit(ctx context.Context, name, key string, opts ...ctdsnapshot.Opt) error {
ctx = namespaces.WithNamespace(ctx, s.ns) ctx = namespaces.WithNamespace(ctx, s.ns)
return s.Snapshotter.Commit(ctx, name, key, opts...) return s.Snapshotter.Commit(ctx, name, key, addRootLabel(opts...))
} }
func (s *nsSnapshotter) Remove(ctx context.Context, key string) error { func (s *nsSnapshotter) Remove(ctx context.Context, key string) error {
ctx = namespaces.WithNamespace(ctx, s.ns) ctx = namespaces.WithNamespace(ctx, s.ns)
@ -64,3 +73,18 @@ func (s *nsSnapshotter) Walk(ctx context.Context, fn func(context.Context, ctdsn
ctx = namespaces.WithNamespace(ctx, s.ns) ctx = namespaces.WithNamespace(ctx, s.ns)
return s.Snapshotter.Walk(ctx, fn) return s.Snapshotter.Walk(ctx, fn)
} }
func addRootLabel(opts ...ctdsnapshot.Opt) ctdsnapshot.Opt {
return func(info *ctdsnapshot.Info) error {
for _, opt := range opts {
if err := opt(info); err != nil {
return err
}
}
if info.Labels == nil {
info.Labels = map[string]string{}
}
info.Labels["containerd.io/gc.root"] = time.Now().UTC().Format(time.RFC3339Nano)
return nil
}
}

View File

@ -1,10 +1,19 @@
package snapshot package snapshot
import ( import (
"context"
"github.com/containerd/containerd/snapshots" "github.com/containerd/containerd/snapshots"
digest "github.com/opencontainers/go-digest"
) )
// Snapshotter defines interface that any snapshot implementation should satisfy // Snapshotter defines interface that any snapshot implementation should satisfy
type Snapshotter interface { type Snapshotter interface {
snapshots.Snapshotter snapshots.Snapshotter
Blobmapper
}
type Blobmapper interface {
GetBlob(ctx context.Context, key string) (digest.Digest, digest.Digest, error)
SetBlob(ctx context.Context, key string, diffID, blob digest.Digest) error
} }

View File

@ -20,6 +20,7 @@ import (
"github.com/moby/buildkit/cache" "github.com/moby/buildkit/cache"
"github.com/moby/buildkit/session" "github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/auth" "github.com/moby/buildkit/session/auth"
"github.com/moby/buildkit/snapshot"
"github.com/moby/buildkit/source" "github.com/moby/buildkit/source"
"github.com/moby/buildkit/util/flightcontrol" "github.com/moby/buildkit/util/flightcontrol"
"github.com/moby/buildkit/util/imageutil" "github.com/moby/buildkit/util/imageutil"
@ -36,17 +37,12 @@ import (
type SourceOpt struct { type SourceOpt struct {
SessionManager *session.Manager SessionManager *session.Manager
Snapshotter snapshots.Snapshotter Snapshotter snapshot.Snapshotter
ContentStore content.Store ContentStore content.Store
Applier diff.Differ Applier diff.Differ
CacheAccessor cache.Accessor CacheAccessor cache.Accessor
} }
type blobmapper interface {
GetBlob(ctx gocontext.Context, key string) (digest.Digest, digest.Digest, error)
SetBlob(ctx gocontext.Context, key string, diffID, blob digest.Digest) error
}
type resolveRecord struct { type resolveRecord struct {
desc ocispec.Descriptor desc ocispec.Descriptor
ts time.Time ts time.Time
@ -62,10 +58,6 @@ func NewSource(opt SourceOpt) (source.Source, error) {
SourceOpt: opt, SourceOpt: opt,
} }
if _, ok := opt.Snapshotter.(blobmapper); !ok {
return nil, errors.Errorf("imagesource requires snapshotter with blobs mapping support")
}
return is, nil return is, nil
} }
@ -280,7 +272,7 @@ func (is *imageSource) fillBlobMapping(ctx context.Context, layers []rootfs.Laye
for _, l := range layers { for _, l := range layers {
chain = append(chain, l.Diff.Digest) chain = append(chain, l.Diff.Digest)
chainID := identity.ChainID(chain) chainID := identity.ChainID(chain)
if err := is.SourceOpt.Snapshotter.(blobmapper).SetBlob(ctx, string(chainID), l.Diff.Digest, l.Blob.Digest); err != nil { if err := is.SourceOpt.Snapshotter.SetBlob(ctx, string(chainID), l.Diff.Digest, l.Blob.Digest); err != nil {
return err return err
} }
} }

View File

@ -10,7 +10,6 @@ import (
"github.com/containerd/containerd/content" "github.com/containerd/containerd/content"
"github.com/containerd/containerd/diff" "github.com/containerd/containerd/diff"
"github.com/containerd/containerd/images" "github.com/containerd/containerd/images"
ctdsnapshot "github.com/containerd/containerd/snapshots"
"github.com/moby/buildkit/cache" "github.com/moby/buildkit/cache"
"github.com/moby/buildkit/cache/cacheimport" "github.com/moby/buildkit/cache/cacheimport"
"github.com/moby/buildkit/cache/instructioncache" "github.com/moby/buildkit/cache/instructioncache"
@ -24,7 +23,7 @@ import (
ociexporter "github.com/moby/buildkit/exporter/oci" ociexporter "github.com/moby/buildkit/exporter/oci"
"github.com/moby/buildkit/identity" "github.com/moby/buildkit/identity"
"github.com/moby/buildkit/session" "github.com/moby/buildkit/session"
"github.com/moby/buildkit/snapshot/blobmapping" "github.com/moby/buildkit/snapshot"
"github.com/moby/buildkit/solver" "github.com/moby/buildkit/solver"
"github.com/moby/buildkit/solver/llbop" "github.com/moby/buildkit/solver/llbop"
"github.com/moby/buildkit/solver/pb" "github.com/moby/buildkit/solver/pb"
@ -49,7 +48,7 @@ type WorkerOpt struct {
SessionManager *session.Manager SessionManager *session.Manager
MetadataStore *metadata.Store MetadataStore *metadata.Store
Executor executor.Executor Executor executor.Executor
BaseSnapshotter ctdsnapshot.Snapshotter // not blobmapping one (FIXME: just require blobmapping snapshotter?) Snapshotter snapshot.Snapshotter
ContentStore content.Store ContentStore content.Store
Applier diff.Differ Applier diff.Differ
Differ diff.Differ Differ diff.Differ
@ -60,7 +59,6 @@ type WorkerOpt struct {
// TODO: s/Worker/OpWorker/g ? // TODO: s/Worker/OpWorker/g ?
type Worker struct { type Worker struct {
WorkerOpt WorkerOpt
Snapshotter ctdsnapshot.Snapshotter // blobmapping snapshotter
CacheManager cache.Manager CacheManager cache.Manager
SourceManager *source.Manager SourceManager *source.Manager
cache instructioncache.InstructionCache cache instructioncache.InstructionCache
@ -73,17 +71,8 @@ type Worker struct {
// NewWorker instantiates a local worker // NewWorker instantiates a local worker
func NewWorker(opt WorkerOpt) (*Worker, error) { func NewWorker(opt WorkerOpt) (*Worker, error) {
bmSnapshotter, err := blobmapping.NewSnapshotter(blobmapping.Opt{
Content: opt.ContentStore,
Snapshotter: opt.BaseSnapshotter,
MetadataStore: opt.MetadataStore,
})
if err != nil {
return nil, err
}
cm, err := cache.NewManager(cache.ManagerOpt{ cm, err := cache.NewManager(cache.ManagerOpt{
Snapshotter: bmSnapshotter, Snapshotter: opt.Snapshotter,
MetadataStore: opt.MetadataStore, MetadataStore: opt.MetadataStore,
}) })
if err != nil { if err != nil {
@ -101,7 +90,7 @@ func NewWorker(opt WorkerOpt) (*Worker, error) {
} }
is, err := containerimage.NewSource(containerimage.SourceOpt{ is, err := containerimage.NewSource(containerimage.SourceOpt{
Snapshotter: bmSnapshotter, Snapshotter: opt.Snapshotter,
ContentStore: opt.ContentStore, ContentStore: opt.ContentStore,
SessionManager: opt.SessionManager, SessionManager: opt.SessionManager,
Applier: opt.Applier, Applier: opt.Applier,
@ -146,7 +135,7 @@ func NewWorker(opt WorkerOpt) (*Worker, error) {
exporters := map[string]exporter.Exporter{} exporters := map[string]exporter.Exporter{}
iw, err := imageexporter.NewImageWriter(imageexporter.WriterOpt{ iw, err := imageexporter.NewImageWriter(imageexporter.WriterOpt{
Snapshotter: bmSnapshotter, Snapshotter: opt.Snapshotter,
ContentStore: opt.ContentStore, ContentStore: opt.ContentStore,
Differ: opt.Differ, Differ: opt.Differ,
}) })
@ -193,14 +182,14 @@ func NewWorker(opt WorkerOpt) (*Worker, error) {
exporters[client.ExporterDocker] = dockerExporter exporters[client.ExporterDocker] = dockerExporter
ce := cacheimport.NewCacheExporter(cacheimport.ExporterOpt{ ce := cacheimport.NewCacheExporter(cacheimport.ExporterOpt{
Snapshotter: bmSnapshotter, Snapshotter: opt.Snapshotter,
ContentStore: opt.ContentStore, ContentStore: opt.ContentStore,
SessionManager: opt.SessionManager, SessionManager: opt.SessionManager,
Differ: opt.Differ, Differ: opt.Differ,
}) })
ci := cacheimport.NewCacheImporter(cacheimport.ImportOpt{ ci := cacheimport.NewCacheImporter(cacheimport.ImportOpt{
Snapshotter: bmSnapshotter, Snapshotter: opt.Snapshotter,
ContentStore: opt.ContentStore, ContentStore: opt.ContentStore,
Applier: opt.Applier, Applier: opt.Applier,
CacheAccessor: cm, CacheAccessor: cm,
@ -209,7 +198,6 @@ func NewWorker(opt WorkerOpt) (*Worker, error) {
return &Worker{ return &Worker{
WorkerOpt: opt, WorkerOpt: opt,
Snapshotter: bmSnapshotter,
CacheManager: cm, CacheManager: cm,
SourceManager: sm, SourceManager: sm,
cache: ic, cache: ic,

View File

@ -5,13 +5,15 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"time"
"github.com/containerd/containerd" "github.com/containerd/containerd"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/snapshots"
"github.com/moby/buildkit/cache/metadata" "github.com/moby/buildkit/cache/metadata"
"github.com/moby/buildkit/executor/containerdexecutor" "github.com/moby/buildkit/executor/containerdexecutor"
"github.com/moby/buildkit/identity" "github.com/moby/buildkit/identity"
"github.com/moby/buildkit/snapshot/nogc" containerdsnapshot "github.com/moby/buildkit/snapshot/containerd"
"github.com/moby/buildkit/worker/base" "github.com/moby/buildkit/worker/base"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -55,10 +57,13 @@ func newContainerd(root string, client *containerd.Client, snapshotterName strin
} }
gc := func(ctx context.Context) error { gc := func(ctx context.Context) error {
// TODO: how to avoid this?
snapshotter := client.SnapshotService(snapshotterName) snapshotter := client.SnapshotService(snapshotterName)
ctx = namespaces.WithNamespace(ctx, "buildkit") ctx = namespaces.WithNamespace(ctx, "buildkit")
key := identity.NewID() key := identity.NewID()
if _, err := snapshotter.Prepare(ctx, key, ""); err != nil { if _, err := snapshotter.Prepare(ctx, key, "", snapshots.WithLabels(map[string]string{
"containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339Nano),
})); err != nil {
return err return err
} }
if err := snapshotter.Remove(ctx, key); err != nil { if err := snapshotter.Remove(ctx, key); err != nil {
@ -67,13 +72,15 @@ func newContainerd(root string, client *containerd.Client, snapshotterName strin
return nil return nil
} }
cs := containerdsnapshot.NewContentStore(client.ContentStore(), "buildkit", gc)
opt := base.WorkerOpt{ opt := base.WorkerOpt{
ID: id, ID: id,
Labels: xlabels, Labels: xlabels,
MetadataStore: md, MetadataStore: md,
Executor: containerdexecutor.New(client, root), Executor: containerdexecutor.New(client, root),
BaseSnapshotter: nogc.NewSnapshotter(client.SnapshotService(snapshotterName), "buildkit", gc), Snapshotter: containerdsnapshot.NewSnapshotter(client.SnapshotService(snapshotterName), cs, md, "buildkit", gc),
ContentStore: nogc.NewContentStore(client.ContentStore(), "buildkit", gc), ContentStore: cs,
Applier: df, Applier: df,
Differ: df, Differ: df,
ImageStore: client.ImageService(), ImageStore: client.ImageService(),

View File

@ -13,7 +13,7 @@ import (
"github.com/containerd/containerd/snapshots/overlay" "github.com/containerd/containerd/snapshots/overlay"
"github.com/moby/buildkit/cache/metadata" "github.com/moby/buildkit/cache/metadata"
"github.com/moby/buildkit/executor/runcexecutor" "github.com/moby/buildkit/executor/runcexecutor"
"github.com/moby/buildkit/snapshot/nogc" containerdsnapshot "github.com/moby/buildkit/snapshot/containerd"
"github.com/moby/buildkit/worker/base" "github.com/moby/buildkit/worker/base"
) )
@ -62,7 +62,7 @@ func NewWorkerOpt(root string, labels map[string]string) (base.WorkerOpt, error)
return err return err
} }
c = nogc.NewContentStore(mdb.ContentStore(), "buildkit", gc) c = containerdsnapshot.NewContentStore(mdb.ContentStore(), "buildkit", gc)
df, err := walking.NewWalkingDiff(c) df, err := walking.NewWalkingDiff(c)
if err != nil { if err != nil {
return opt, err return opt, err
@ -81,7 +81,7 @@ func NewWorkerOpt(root string, labels map[string]string) (base.WorkerOpt, error)
Labels: xlabels, Labels: xlabels,
MetadataStore: md, MetadataStore: md,
Executor: exe, Executor: exe,
BaseSnapshotter: nogc.NewSnapshotter(mdb.Snapshotter("overlayfs"), "buildkit", gc), Snapshotter: containerdsnapshot.NewSnapshotter(mdb.Snapshotter("overlayfs"), c, md, "buildkit", gc),
ContentStore: c, ContentStore: c,
Applier: df, Applier: df,
Differ: df, Differ: df,