mirror of
https://github.com/moby/moby.git
synced 2026-08-04 15:11:00 +00:00
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>
129 lines
3.8 KiB
Go
129 lines
3.8 KiB
Go
package build // import "github.com/docker/docker/api/server/backend/build"
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strconv"
|
|
|
|
"github.com/distribution/reference"
|
|
"github.com/docker/docker/api/types"
|
|
"github.com/docker/docker/api/types/backend"
|
|
"github.com/docker/docker/api/types/events"
|
|
"github.com/docker/docker/builder"
|
|
buildkit "github.com/docker/docker/builder/builder-next"
|
|
daemonevents "github.com/docker/docker/daemon/events"
|
|
"github.com/docker/docker/image"
|
|
"github.com/docker/docker/pkg/stringid"
|
|
"github.com/pkg/errors"
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
// ImageComponent provides an interface for working with images
|
|
type ImageComponent interface {
|
|
SquashImage(from string, to string) (string, error)
|
|
TagImage(context.Context, image.ID, reference.Named) error
|
|
}
|
|
|
|
// Builder defines interface for running a build
|
|
type Builder interface {
|
|
Build(context.Context, backend.BuildConfig) (*builder.Result, error)
|
|
}
|
|
|
|
// Backend provides build functionality to the API router
|
|
type Backend struct {
|
|
builder Builder
|
|
imageComponent ImageComponent
|
|
buildkit *buildkit.Builder
|
|
eventsService *daemonevents.Events
|
|
}
|
|
|
|
// NewBackend creates a new build backend from components
|
|
func NewBackend(components ImageComponent, builder Builder, buildkit *buildkit.Builder, es *daemonevents.Events) (*Backend, error) {
|
|
return &Backend{imageComponent: components, builder: builder, buildkit: buildkit, eventsService: es}, nil
|
|
}
|
|
|
|
// RegisterGRPC registers buildkit controller to the grpc server.
|
|
func (b *Backend) RegisterGRPC(s *grpc.Server) {
|
|
if b.buildkit != nil {
|
|
b.buildkit.RegisterGRPC(s)
|
|
}
|
|
}
|
|
|
|
// Build builds an image from a Source
|
|
func (b *Backend) Build(ctx context.Context, config backend.BuildConfig) (string, error) {
|
|
options := config.Options
|
|
useBuildKit := options.Version == types.BuilderBuildKit
|
|
|
|
tags, err := sanitizeRepoAndTags(options.Tags)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
var build *builder.Result
|
|
if useBuildKit {
|
|
build, err = b.buildkit.Build(ctx, config)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
} else {
|
|
build, err = b.builder.Build(ctx, config)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
|
|
if build == nil {
|
|
return "", nil
|
|
}
|
|
|
|
imageID := build.ImageID
|
|
if options.Squash {
|
|
if imageID, err = squashBuild(build, b.imageComponent); err != nil {
|
|
return "", err
|
|
}
|
|
if config.ProgressWriter.AuxFormatter != nil {
|
|
if err = config.ProgressWriter.AuxFormatter.Emit("moby.image.id", types.BuildResult{ID: imageID}); err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
// PruneCache removes all cached build sources
|
|
func (b *Backend) PruneCache(ctx context.Context, opts types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error) {
|
|
buildCacheSize, cacheIDs, err := b.buildkit.Prune(ctx, opts)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to prune build cache")
|
|
}
|
|
b.eventsService.Log(events.ActionPrune, events.BuilderEventType, events.Actor{
|
|
Attributes: map[string]string{
|
|
"reclaimed": strconv.FormatInt(buildCacheSize, 10),
|
|
},
|
|
})
|
|
return &types.BuildCachePruneReport{SpaceReclaimed: uint64(buildCacheSize), CachesDeleted: cacheIDs}, nil
|
|
}
|
|
|
|
// Cancel cancels the build by ID
|
|
func (b *Backend) Cancel(ctx context.Context, id string) error {
|
|
return b.buildkit.Cancel(ctx, id)
|
|
}
|
|
|
|
func squashBuild(build *builder.Result, imageComponent ImageComponent) (string, error) {
|
|
var fromID string
|
|
if build.FromImage != nil {
|
|
fromID = build.FromImage.ImageID()
|
|
}
|
|
imageID, err := imageComponent.SquashImage(build.ImageID, fromID)
|
|
if err != nil {
|
|
return "", errors.Wrap(err, "error squashing image")
|
|
}
|
|
return imageID, nil
|
|
}
|