mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
builder-next: fixes for inline cache support
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
parent
7ac4e33e63
commit
ddaba80467
3 changed files with 89 additions and 7 deletions
|
@ -12,12 +12,22 @@ import (
|
|||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
func (s *snapshotter) EnsureLayer(ctx context.Context, key string) ([]layer.DiffID, error) {
|
||||
func (s *snapshotter) GetDiffIDs(ctx context.Context, key string) ([]layer.DiffID, error) {
|
||||
if l, err := s.getLayer(key, true); err != nil {
|
||||
return nil, err
|
||||
} else if l != nil {
|
||||
return getDiffChain(l), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *snapshotter) EnsureLayer(ctx context.Context, key string) ([]layer.DiffID, error) {
|
||||
diffIDs, err := s.GetDiffIDs(ctx, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if diffIDs != nil {
|
||||
return diffIDs, nil
|
||||
}
|
||||
|
||||
id, committed := s.getGraphDriverID(key)
|
||||
if !committed {
|
||||
|
|
|
@ -136,6 +136,11 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) {
|
|||
return nil, errors.Wrap(err, "could not get builder GC policy")
|
||||
}
|
||||
|
||||
layers, ok := sbase.(mobyworker.LayerAccess)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("snapshotter doesn't support differ")
|
||||
}
|
||||
|
||||
wopt := mobyworker.Opt{
|
||||
ID: "moby",
|
||||
MetadataStore: md,
|
||||
|
@ -149,6 +154,7 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) {
|
|||
V2MetadataService: dist.V2MetadataService,
|
||||
Exporter: exp,
|
||||
Transport: rt,
|
||||
Layers: layers,
|
||||
}
|
||||
|
||||
wc := &worker.Controller{}
|
||||
|
@ -174,7 +180,6 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) {
|
|||
ResolveCacheExporterFuncs: map[string]remotecache.ResolveCacheExporterFunc{
|
||||
"inline": inlineremotecache.ResolveCacheExporterFunc(),
|
||||
},
|
||||
// TODO: set ResolveCacheExporterFunc for exporting cache
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/rootfs"
|
||||
"github.com/docker/docker/distribution"
|
||||
|
@ -43,6 +44,14 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const labelCreatedAt = "buildkit/createdat"
|
||||
|
||||
// LayerAccess provides access to a moby layer from a snapshot
|
||||
type LayerAccess interface {
|
||||
GetDiffIDs(ctx context.Context, key string) ([]layer.DiffID, error)
|
||||
EnsureLayer(ctx context.Context, key string) ([]layer.DiffID, error)
|
||||
}
|
||||
|
||||
// Opt defines a structure for creating a worker.
|
||||
type Opt struct {
|
||||
ID string
|
||||
|
@ -58,6 +67,7 @@ type Opt struct {
|
|||
V2MetadataService distmetadata.V2MetadataService
|
||||
Transport nethttp.RoundTripper
|
||||
Exporter exporter.Exporter
|
||||
Layers LayerAccess
|
||||
}
|
||||
|
||||
// Worker is a local worker instance with dedicated snapshotter, cache, and so on.
|
||||
|
@ -205,7 +215,36 @@ func (w *Worker) Exporter(name string, sm *session.Manager) (exporter.Exporter,
|
|||
|
||||
// GetRemote returns a remote snapshot reference for a local one
|
||||
func (w *Worker) GetRemote(ctx context.Context, ref cache.ImmutableRef, createIfNeeded bool) (*solver.Remote, error) {
|
||||
return nil, errors.Errorf("getremote not implemented")
|
||||
var diffIDs []layer.DiffID
|
||||
var err error
|
||||
if !createIfNeeded {
|
||||
diffIDs, err = w.Layers.GetDiffIDs(ctx, ref.ID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if err := ref.Finalize(ctx, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
diffIDs, err = w.Layers.EnsureLayer(ctx, ref.ID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
descriptors := make([]ocispec.Descriptor, len(diffIDs))
|
||||
for i, dgst := range diffIDs {
|
||||
descriptors[i] = ocispec.Descriptor{
|
||||
MediaType: images.MediaTypeDockerSchema2Layer,
|
||||
Digest: digest.Digest(dgst),
|
||||
Size: -1,
|
||||
}
|
||||
}
|
||||
|
||||
return &solver.Remote{
|
||||
Descriptors: descriptors,
|
||||
Provider: &emptyProvider{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FromRemote converts a remote snapshot reference to a local one
|
||||
|
@ -241,11 +280,32 @@ func (w *Worker) FromRemote(ctx context.Context, remote *solver.Remote) (cache.I
|
|||
}
|
||||
defer release()
|
||||
|
||||
ref, err := w.CacheManager.GetFromSnapshotter(ctx, string(rootFS.ChainID()), cache.WithDescription(fmt.Sprintf("imported %s", remote.Descriptors[len(remote.Descriptors)-1].Digest)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if len(rootFS.DiffIDs) != len(layers) {
|
||||
return nil, errors.Errorf("invalid layer count mismatch %d vs %d", len(rootFS.DiffIDs), len(layers))
|
||||
}
|
||||
return ref, nil
|
||||
|
||||
for i := range rootFS.DiffIDs {
|
||||
tm := time.Now()
|
||||
if tmstr, ok := remote.Descriptors[i].Annotations[labelCreatedAt]; ok {
|
||||
if err := (&tm).UnmarshalText([]byte(tmstr)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
descr := fmt.Sprintf("imported %s", remote.Descriptors[i].Digest)
|
||||
if v, ok := remote.Descriptors[i].Annotations["buildkit/description"]; ok {
|
||||
descr = v
|
||||
}
|
||||
ref, err := w.CacheManager.GetFromSnapshotter(ctx, string(layer.CreateChainID(rootFS.DiffIDs[:i+1])), cache.WithDescription(descr), cache.WithCreationTime(tm))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if i == len(remote.Descriptors)-1 {
|
||||
return ref, nil
|
||||
}
|
||||
defer ref.Release(context.TODO())
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("unreachable")
|
||||
}
|
||||
|
||||
type discardProgress struct{}
|
||||
|
@ -344,3 +404,10 @@ func oneOffProgress(ctx context.Context, id string) func(err error) error {
|
|||
type resolveImageConfig interface {
|
||||
ResolveImageConfig(ctx context.Context, ref string, opt gw.ResolveImageConfigOpt, sm *session.Manager) (digest.Digest, []byte, error)
|
||||
}
|
||||
|
||||
type emptyProvider struct {
|
||||
}
|
||||
|
||||
func (p *emptyProvider) ReaderAt(ctx context.Context, dec ocispec.Descriptor) (content.ReaderAt, error) {
|
||||
return nil, errors.Errorf("ReaderAt not implemented for empty provider")
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue