snapshot: clean up snapshot interface
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>docker-18.09
parent
56353f99a8
commit
b0679c66db
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package nogc
|
package containerd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
@ -44,23 +43,22 @@ import (
|
||||||
// WorkerOpt is specific to a worker.
|
// WorkerOpt is specific to a worker.
|
||||||
// See also CommonOpt.
|
// See also CommonOpt.
|
||||||
type WorkerOpt struct {
|
type WorkerOpt struct {
|
||||||
ID string
|
ID string
|
||||||
Labels map[string]string
|
Labels map[string]string
|
||||||
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
|
||||||
ImageStore images.Store // optional
|
ImageStore images.Store // optional
|
||||||
}
|
}
|
||||||
|
|
||||||
// Worker is a local worker instance with dedicated snapshotter, cache, and so on.
|
// Worker is a local worker instance with dedicated snapshotter, cache, and so on.
|
||||||
// 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,
|
||||||
|
|
|
@ -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,16 +72,18 @@ 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(),
|
||||||
}
|
}
|
||||||
return opt, nil
|
return opt, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
@ -77,15 +77,15 @@ func NewWorkerOpt(root string, labels map[string]string) (base.WorkerOpt, error)
|
||||||
xlabels[k] = v
|
xlabels[k] = v
|
||||||
}
|
}
|
||||||
opt = base.WorkerOpt{
|
opt = base.WorkerOpt{
|
||||||
ID: id,
|
ID: id,
|
||||||
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,
|
||||||
ImageStore: nil, // explicitly
|
ImageStore: nil, // explicitly
|
||||||
}
|
}
|
||||||
return opt, nil
|
return opt, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue