mirror of
https://github.com/moby/moby.git
synced 2026-08-04 23:21:00 +00:00
builder-next: Add ImageNamedByBuildkit callback
When image is built with buildkit with containerd integration the image
service has no way of knowing that the image was tagged because buildkit
creates the image directly in containerd image store.
Add a callback that is called by the exporter wrapper.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 1506bbcfe8)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
@@ -88,11 +88,9 @@ func (b *Backend) Build(ctx context.Context, config backend.BuildConfig) (string
|
||||
}
|
||||
}
|
||||
|
||||
if !useBuildKit {
|
||||
stdout := config.ProgressWriter.StdoutFormatter
|
||||
fmt.Fprintf(stdout, "Successfully built %s\n", stringid.TruncateID(imageID))
|
||||
}
|
||||
if imageID != "" && !useBuildKit {
|
||||
stdout := config.ProgressWriter.StdoutFormatter
|
||||
_, _ = fmt.Fprintf(stdout, "Successfully built %s\n", stringid.TruncateID(imageID))
|
||||
err = tagImages(ctx, b.imageComponent, config.ProgressWriter.StdoutFormatter, image.ID(imageID), tags)
|
||||
}
|
||||
return imageID, err
|
||||
|
||||
@@ -77,24 +77,24 @@ var cacheFields = map[string]bool{
|
||||
|
||||
// Opt is option struct required for creating the builder
|
||||
type Opt struct {
|
||||
SessionManager *session.Manager
|
||||
Root string
|
||||
EngineID string
|
||||
Dist images.DistributionServices
|
||||
ImageTagger mobyexporter.ImageTagger
|
||||
NetworkController *libnetwork.Controller
|
||||
DefaultCgroupParent string
|
||||
RegistryHosts docker.RegistryHosts
|
||||
BuilderConfig config.BuilderConfig
|
||||
Rootless bool
|
||||
IdentityMapping idtools.IdentityMapping
|
||||
DNSConfig config.DNSConfig
|
||||
ApparmorProfile string
|
||||
UseSnapshotter bool
|
||||
Snapshotter string
|
||||
ContainerdAddress string
|
||||
ContainerdNamespace string
|
||||
ImageExportedCallback exporter.ImageExportedByBuildkit
|
||||
SessionManager *session.Manager
|
||||
Root string
|
||||
EngineID string
|
||||
Dist images.DistributionServices
|
||||
ImageTagger mobyexporter.ImageTagger
|
||||
NetworkController *libnetwork.Controller
|
||||
DefaultCgroupParent string
|
||||
RegistryHosts docker.RegistryHosts
|
||||
BuilderConfig config.BuilderConfig
|
||||
Rootless bool
|
||||
IdentityMapping idtools.IdentityMapping
|
||||
DNSConfig config.DNSConfig
|
||||
ApparmorProfile string
|
||||
UseSnapshotter bool
|
||||
Snapshotter string
|
||||
ContainerdAddress string
|
||||
ContainerdNamespace string
|
||||
Callbacks exporter.BuildkitCallbacks
|
||||
}
|
||||
|
||||
// Builder can build using BuildKit backend
|
||||
|
||||
@@ -138,7 +138,7 @@ func newSnapshotterController(ctx context.Context, rt http.RoundTripper, opt Opt
|
||||
}
|
||||
wo.Executor = exec
|
||||
|
||||
w, err := mobyworker.NewContainerdWorker(ctx, wo, opt.ImageExportedCallback)
|
||||
w, err := mobyworker.NewContainerdWorker(ctx, wo, opt.Callbacks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -321,7 +321,8 @@ func newGraphDriverController(ctx context.Context, rt http.RoundTripper, opt Opt
|
||||
Differ: differ,
|
||||
ImageTagger: opt.ImageTagger,
|
||||
LeaseManager: lm,
|
||||
ImageExportedCallback: opt.ImageExportedCallback,
|
||||
ImageExportedCallback: opt.Callbacks.Exported,
|
||||
// Callbacks.Named is not used here because the tag operation is handled directly by the image service.
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/containerd/containerd/leases"
|
||||
"github.com/containerd/log"
|
||||
distref "github.com/distribution/reference"
|
||||
builderexporter "github.com/docker/docker/builder/builder-next/exporter"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/layer"
|
||||
"github.com/moby/buildkit/exporter"
|
||||
@@ -38,7 +37,7 @@ type Opt struct {
|
||||
ImageTagger ImageTagger
|
||||
ContentStore content.Store
|
||||
LeaseManager leases.Manager
|
||||
ImageExportedCallback builderexporter.ImageExportedByBuildkit
|
||||
ImageExportedCallback func(ctx context.Context, id string, desc ocispec.Descriptor)
|
||||
}
|
||||
|
||||
type imageExporter struct {
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/builder/builder-next/exporter/overrides"
|
||||
"github.com/moby/buildkit/exporter"
|
||||
"github.com/moby/buildkit/exporter/containerimage/exptypes"
|
||||
@@ -11,19 +13,29 @@ import (
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
type ImageExportedByBuildkit = func(ctx context.Context, id string, desc ocispec.Descriptor)
|
||||
type BuildkitCallbacks struct {
|
||||
// Exported is a Called when an image is exported by buildkit.
|
||||
Exported func(ctx context.Context, id string, desc ocispec.Descriptor)
|
||||
|
||||
// Named is a callback that is called when an image is created in the
|
||||
// containerd image store by buildkit.
|
||||
Named func(ctx context.Context, ref reference.NamedTagged, desc ocispec.Descriptor)
|
||||
}
|
||||
|
||||
// Wraps the containerimage exporter's Resolve method to apply moby-specific
|
||||
// overrides to the exporter attributes.
|
||||
type imageExporterMobyWrapper struct {
|
||||
exp exporter.Exporter
|
||||
callback ImageExportedByBuildkit
|
||||
exp exporter.Exporter
|
||||
callbacks BuildkitCallbacks
|
||||
}
|
||||
|
||||
// NewWrapper returns an exporter wrapper that applies moby specific attributes
|
||||
// and hooks the export process.
|
||||
func NewWrapper(exp exporter.Exporter, callback ImageExportedByBuildkit) (exporter.Exporter, error) {
|
||||
return &imageExporterMobyWrapper{exp: exp, callback: callback}, nil
|
||||
func NewWrapper(exp exporter.Exporter, callbacks BuildkitCallbacks) (exporter.Exporter, error) {
|
||||
return &imageExporterMobyWrapper{
|
||||
exp: exp,
|
||||
callbacks: callbacks,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Resolve applies moby specific attributes to the request.
|
||||
@@ -46,12 +58,15 @@ func (e *imageExporterMobyWrapper) Resolve(ctx context.Context, id int, exporter
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &imageExporterInstanceWrapper{ExporterInstance: inst, callback: e.callback}, nil
|
||||
return &imageExporterInstanceWrapper{
|
||||
ExporterInstance: inst,
|
||||
callbacks: e.callbacks,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type imageExporterInstanceWrapper struct {
|
||||
exporter.ExporterInstance
|
||||
callback ImageExportedByBuildkit
|
||||
callbacks BuildkitCallbacks
|
||||
}
|
||||
|
||||
func (i *imageExporterInstanceWrapper) Export(ctx context.Context, src *exporter.Source, inlineCache exptypes.InlineCache, sessionID string) (map[string]string, exporter.DescriptorReference, error) {
|
||||
@@ -62,8 +77,26 @@ func (i *imageExporterInstanceWrapper) Export(ctx context.Context, src *exporter
|
||||
|
||||
desc := ref.Descriptor()
|
||||
imageID := out[exptypes.ExporterImageDigestKey]
|
||||
if i.callback != nil {
|
||||
i.callback(ctx, imageID, desc)
|
||||
if i.callbacks.Exported != nil {
|
||||
i.callbacks.Exported(ctx, imageID, desc)
|
||||
}
|
||||
|
||||
if i.callbacks.Named != nil {
|
||||
for _, name := range strings.Split(out[string(exptypes.OptKeyName)], ",") {
|
||||
ref, err := reference.ParseNormalizedNamed(name)
|
||||
if err != nil {
|
||||
// Shouldn't happen, but log if it does and continue.
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"name": name,
|
||||
"error": err,
|
||||
}).Warn("image named with invalid reference produced by buildkit")
|
||||
continue
|
||||
}
|
||||
|
||||
namedTagged := reference.TagNameOnly(ref).(reference.NamedTagged)
|
||||
i.callbacks.Named(ctx, namedTagged, desc)
|
||||
}
|
||||
}
|
||||
|
||||
return out, ref, nil
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package worker
|
||||
import (
|
||||
"context"
|
||||
|
||||
mobyexporter "github.com/docker/docker/builder/builder-next/exporter"
|
||||
"github.com/docker/docker/builder/builder-next/exporter"
|
||||
"github.com/moby/buildkit/client"
|
||||
"github.com/moby/buildkit/exporter"
|
||||
bkexporter "github.com/moby/buildkit/exporter"
|
||||
"github.com/moby/buildkit/session"
|
||||
"github.com/moby/buildkit/worker/base"
|
||||
)
|
||||
@@ -13,27 +13,27 @@ import (
|
||||
// ContainerdWorker is a local worker instance with dedicated snapshotter, cache, and so on.
|
||||
type ContainerdWorker struct {
|
||||
*base.Worker
|
||||
callback mobyexporter.ImageExportedByBuildkit
|
||||
callbacks exporter.BuildkitCallbacks
|
||||
}
|
||||
|
||||
// NewContainerdWorker instantiates a local worker.
|
||||
func NewContainerdWorker(ctx context.Context, wo base.WorkerOpt, callback mobyexporter.ImageExportedByBuildkit) (*ContainerdWorker, error) {
|
||||
func NewContainerdWorker(ctx context.Context, wo base.WorkerOpt, callbacks exporter.BuildkitCallbacks) (*ContainerdWorker, error) {
|
||||
bw, err := base.NewWorker(ctx, wo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ContainerdWorker{Worker: bw, callback: callback}, nil
|
||||
return &ContainerdWorker{Worker: bw, callbacks: callbacks}, nil
|
||||
}
|
||||
|
||||
// Exporter returns exporter by name
|
||||
func (w *ContainerdWorker) Exporter(name string, sm *session.Manager) (exporter.Exporter, error) {
|
||||
func (w *ContainerdWorker) Exporter(name string, sm *session.Manager) (bkexporter.Exporter, error) {
|
||||
switch name {
|
||||
case mobyexporter.Moby:
|
||||
case exporter.Moby:
|
||||
exp, err := w.Worker.Exporter(client.ExporterImage, sm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mobyexporter.NewWrapper(exp, w.callback)
|
||||
return exporter.NewWrapper(exp, w.callbacks)
|
||||
default:
|
||||
return w.Worker.Exporter(name, sm)
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
systemrouter "github.com/docker/docker/api/server/router/system"
|
||||
"github.com/docker/docker/api/server/router/volume"
|
||||
buildkit "github.com/docker/docker/builder/builder-next"
|
||||
"github.com/docker/docker/builder/builder-next/exporter"
|
||||
"github.com/docker/docker/builder/dockerfile"
|
||||
"github.com/docker/docker/cmd/dockerd/debug"
|
||||
"github.com/docker/docker/cmd/dockerd/trap"
|
||||
@@ -430,24 +431,26 @@ func newRouterOptions(ctx context.Context, config *config.Config, d *daemon.Daem
|
||||
cgroupParent := newCgroupParent(config)
|
||||
|
||||
bk, err := buildkit.New(ctx, buildkit.Opt{
|
||||
SessionManager: sm,
|
||||
Root: filepath.Join(config.Root, "buildkit"),
|
||||
EngineID: d.ID(),
|
||||
Dist: d.DistributionServices(),
|
||||
ImageTagger: d.ImageService(),
|
||||
NetworkController: d.NetworkController(),
|
||||
DefaultCgroupParent: cgroupParent,
|
||||
RegistryHosts: d.RegistryHosts,
|
||||
BuilderConfig: config.Builder,
|
||||
Rootless: daemon.Rootless(config),
|
||||
IdentityMapping: d.IdentityMapping(),
|
||||
DNSConfig: config.DNSConfig,
|
||||
ApparmorProfile: daemon.DefaultApparmorProfile(),
|
||||
UseSnapshotter: d.UsesSnapshotter(),
|
||||
Snapshotter: d.ImageService().StorageDriver(),
|
||||
ContainerdAddress: config.ContainerdAddr,
|
||||
ContainerdNamespace: config.ContainerdNamespace,
|
||||
ImageExportedCallback: d.ImageExportedByBuildkit,
|
||||
SessionManager: sm,
|
||||
Root: filepath.Join(config.Root, "buildkit"),
|
||||
EngineID: d.ID(),
|
||||
Dist: d.DistributionServices(),
|
||||
ImageTagger: d.ImageService(),
|
||||
NetworkController: d.NetworkController(),
|
||||
DefaultCgroupParent: cgroupParent,
|
||||
RegistryHosts: d.RegistryHosts,
|
||||
BuilderConfig: config.Builder,
|
||||
Rootless: daemon.Rootless(config),
|
||||
IdentityMapping: d.IdentityMapping(),
|
||||
DNSConfig: config.DNSConfig,
|
||||
ApparmorProfile: daemon.DefaultApparmorProfile(),
|
||||
UseSnapshotter: d.UsesSnapshotter(),
|
||||
Snapshotter: d.ImageService().StorageDriver(),
|
||||
ContainerdAddress: config.ContainerdAddr,
|
||||
ContainerdNamespace: config.ContainerdNamespace,
|
||||
Callbacks: exporter.BuildkitCallbacks{
|
||||
Exported: d.ImageExportedByBuildkit,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return routerOptions{}, err
|
||||
|
||||
Reference in New Issue
Block a user