2018-02-05 16:05:59 -05:00
|
|
|
package build // import "github.com/docker/docker/api/server/backend/build"
|
2017-04-13 14:37:32 -04:00
|
|
|
|
|
|
|
import (
|
2018-04-19 18:30:59 -04:00
|
|
|
"context"
|
2017-04-13 14:37:32 -04:00
|
|
|
"fmt"
|
API: add "prune" events
This patch adds a new "prune" event type to indicate that pruning of a resource
type completed.
This event-type can be used on systems that want to perform actions after
resources have been cleaned up. For example, Docker Desktop performs an fstrim
after resources are deleted (https://github.com/linuxkit/linuxkit/tree/v0.7/pkg/trim-after-delete).
While the current (remove, destroy) events can provide information on _most_
resources, there is currently no event triggered after the BuildKit build-cache
is cleaned.
Prune events have a `reclaimed` attribute, indicating the amount of space that
was reclaimed (in bytes). The attribute can be used, for example, to use as a
threshold for performing fstrim actions. Reclaimed space for `network` events
will always be 0, but the field is added to be consistent with prune events for
other resources.
To test this patch:
Create some resources:
for i in foo bar baz; do \
docker network create network_$i \
&& docker volume create volume_$i \
&& docker run -d --name container_$i -v volume_$i:/volume busybox sh -c 'truncate -s 5M somefile; truncate -s 5M /volume/file' \
&& docker tag busybox:latest image_$i; \
done;
docker pull alpine
docker pull nginx:alpine
echo -e "FROM busybox\nRUN truncate -s 50M bigfile" | DOCKER_BUILDKIT=1 docker build -
Start listening for "prune" events in another shell:
docker events --filter event=prune
Prune containers, networks, volumes, and build-cache:
docker system prune -af --volumes
See the events that are returned:
docker events --filter event=prune
2020-07-25T12:12:09.268491000Z container prune (reclaimed=15728640)
2020-07-25T12:12:09.447890400Z network prune (reclaimed=0)
2020-07-25T12:12:09.452323000Z volume prune (reclaimed=15728640)
2020-07-25T12:12:09.517236200Z image prune (reclaimed=21568540)
2020-07-25T12:12:09.566662600Z builder prune (reclaimed=52428841)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-07-25 08:14:38 -04:00
|
|
|
"strconv"
|
2017-04-13 14:37:32 -04:00
|
|
|
|
|
|
|
"github.com/docker/distribution/reference"
|
2017-05-15 17:54:27 -04:00
|
|
|
"github.com/docker/docker/api/types"
|
2017-04-13 14:37:32 -04:00
|
|
|
"github.com/docker/docker/api/types/backend"
|
API: add "prune" events
This patch adds a new "prune" event type to indicate that pruning of a resource
type completed.
This event-type can be used on systems that want to perform actions after
resources have been cleaned up. For example, Docker Desktop performs an fstrim
after resources are deleted (https://github.com/linuxkit/linuxkit/tree/v0.7/pkg/trim-after-delete).
While the current (remove, destroy) events can provide information on _most_
resources, there is currently no event triggered after the BuildKit build-cache
is cleaned.
Prune events have a `reclaimed` attribute, indicating the amount of space that
was reclaimed (in bytes). The attribute can be used, for example, to use as a
threshold for performing fstrim actions. Reclaimed space for `network` events
will always be 0, but the field is added to be consistent with prune events for
other resources.
To test this patch:
Create some resources:
for i in foo bar baz; do \
docker network create network_$i \
&& docker volume create volume_$i \
&& docker run -d --name container_$i -v volume_$i:/volume busybox sh -c 'truncate -s 5M somefile; truncate -s 5M /volume/file' \
&& docker tag busybox:latest image_$i; \
done;
docker pull alpine
docker pull nginx:alpine
echo -e "FROM busybox\nRUN truncate -s 50M bigfile" | DOCKER_BUILDKIT=1 docker build -
Start listening for "prune" events in another shell:
docker events --filter event=prune
Prune containers, networks, volumes, and build-cache:
docker system prune -af --volumes
See the events that are returned:
docker events --filter event=prune
2020-07-25T12:12:09.268491000Z container prune (reclaimed=15728640)
2020-07-25T12:12:09.447890400Z network prune (reclaimed=0)
2020-07-25T12:12:09.452323000Z volume prune (reclaimed=15728640)
2020-07-25T12:12:09.517236200Z image prune (reclaimed=21568540)
2020-07-25T12:12:09.566662600Z builder prune (reclaimed=52428841)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-07-25 08:14:38 -04:00
|
|
|
"github.com/docker/docker/api/types/events"
|
2017-04-13 14:37:32 -04:00
|
|
|
"github.com/docker/docker/builder"
|
2018-04-17 18:50:17 -04:00
|
|
|
buildkit "github.com/docker/docker/builder/builder-next"
|
API: add "prune" events
This patch adds a new "prune" event type to indicate that pruning of a resource
type completed.
This event-type can be used on systems that want to perform actions after
resources have been cleaned up. For example, Docker Desktop performs an fstrim
after resources are deleted (https://github.com/linuxkit/linuxkit/tree/v0.7/pkg/trim-after-delete).
While the current (remove, destroy) events can provide information on _most_
resources, there is currently no event triggered after the BuildKit build-cache
is cleaned.
Prune events have a `reclaimed` attribute, indicating the amount of space that
was reclaimed (in bytes). The attribute can be used, for example, to use as a
threshold for performing fstrim actions. Reclaimed space for `network` events
will always be 0, but the field is added to be consistent with prune events for
other resources.
To test this patch:
Create some resources:
for i in foo bar baz; do \
docker network create network_$i \
&& docker volume create volume_$i \
&& docker run -d --name container_$i -v volume_$i:/volume busybox sh -c 'truncate -s 5M somefile; truncate -s 5M /volume/file' \
&& docker tag busybox:latest image_$i; \
done;
docker pull alpine
docker pull nginx:alpine
echo -e "FROM busybox\nRUN truncate -s 50M bigfile" | DOCKER_BUILDKIT=1 docker build -
Start listening for "prune" events in another shell:
docker events --filter event=prune
Prune containers, networks, volumes, and build-cache:
docker system prune -af --volumes
See the events that are returned:
docker events --filter event=prune
2020-07-25T12:12:09.268491000Z container prune (reclaimed=15728640)
2020-07-25T12:12:09.447890400Z network prune (reclaimed=0)
2020-07-25T12:12:09.452323000Z volume prune (reclaimed=15728640)
2020-07-25T12:12:09.517236200Z image prune (reclaimed=21568540)
2020-07-25T12:12:09.566662600Z builder prune (reclaimed=52428841)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-07-25 08:14:38 -04:00
|
|
|
daemonevents "github.com/docker/docker/daemon/events"
|
2017-04-13 14:37:32 -04:00
|
|
|
"github.com/docker/docker/image"
|
|
|
|
"github.com/docker/docker/pkg/stringid"
|
|
|
|
"github.com/pkg/errors"
|
2019-04-02 00:08:51 -04:00
|
|
|
"google.golang.org/grpc"
|
2017-04-13 14:37:32 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
// ImageComponent provides an interface for working with images
|
|
|
|
type ImageComponent interface {
|
|
|
|
SquashImage(from string, to string) (string, error)
|
2017-08-24 14:48:16 -04:00
|
|
|
TagImageWithReference(image.ID, reference.Named) error
|
2017-04-13 14:37:32 -04:00
|
|
|
}
|
|
|
|
|
2017-05-15 17:54:27 -04:00
|
|
|
// Builder defines interface for running a build
|
|
|
|
type Builder interface {
|
|
|
|
Build(context.Context, backend.BuildConfig) (*builder.Result, error)
|
|
|
|
}
|
|
|
|
|
2017-04-13 14:37:32 -04:00
|
|
|
// Backend provides build functionality to the API router
|
|
|
|
type Backend struct {
|
2017-05-15 17:54:27 -04:00
|
|
|
builder Builder
|
2017-04-13 14:37:32 -04:00
|
|
|
imageComponent ImageComponent
|
2018-04-17 18:50:17 -04:00
|
|
|
buildkit *buildkit.Builder
|
API: add "prune" events
This patch adds a new "prune" event type to indicate that pruning of a resource
type completed.
This event-type can be used on systems that want to perform actions after
resources have been cleaned up. For example, Docker Desktop performs an fstrim
after resources are deleted (https://github.com/linuxkit/linuxkit/tree/v0.7/pkg/trim-after-delete).
While the current (remove, destroy) events can provide information on _most_
resources, there is currently no event triggered after the BuildKit build-cache
is cleaned.
Prune events have a `reclaimed` attribute, indicating the amount of space that
was reclaimed (in bytes). The attribute can be used, for example, to use as a
threshold for performing fstrim actions. Reclaimed space for `network` events
will always be 0, but the field is added to be consistent with prune events for
other resources.
To test this patch:
Create some resources:
for i in foo bar baz; do \
docker network create network_$i \
&& docker volume create volume_$i \
&& docker run -d --name container_$i -v volume_$i:/volume busybox sh -c 'truncate -s 5M somefile; truncate -s 5M /volume/file' \
&& docker tag busybox:latest image_$i; \
done;
docker pull alpine
docker pull nginx:alpine
echo -e "FROM busybox\nRUN truncate -s 50M bigfile" | DOCKER_BUILDKIT=1 docker build -
Start listening for "prune" events in another shell:
docker events --filter event=prune
Prune containers, networks, volumes, and build-cache:
docker system prune -af --volumes
See the events that are returned:
docker events --filter event=prune
2020-07-25T12:12:09.268491000Z container prune (reclaimed=15728640)
2020-07-25T12:12:09.447890400Z network prune (reclaimed=0)
2020-07-25T12:12:09.452323000Z volume prune (reclaimed=15728640)
2020-07-25T12:12:09.517236200Z image prune (reclaimed=21568540)
2020-07-25T12:12:09.566662600Z builder prune (reclaimed=52428841)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-07-25 08:14:38 -04:00
|
|
|
eventsService *daemonevents.Events
|
2017-04-13 14:37:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewBackend creates a new build backend from components
|
API: add "prune" events
This patch adds a new "prune" event type to indicate that pruning of a resource
type completed.
This event-type can be used on systems that want to perform actions after
resources have been cleaned up. For example, Docker Desktop performs an fstrim
after resources are deleted (https://github.com/linuxkit/linuxkit/tree/v0.7/pkg/trim-after-delete).
While the current (remove, destroy) events can provide information on _most_
resources, there is currently no event triggered after the BuildKit build-cache
is cleaned.
Prune events have a `reclaimed` attribute, indicating the amount of space that
was reclaimed (in bytes). The attribute can be used, for example, to use as a
threshold for performing fstrim actions. Reclaimed space for `network` events
will always be 0, but the field is added to be consistent with prune events for
other resources.
To test this patch:
Create some resources:
for i in foo bar baz; do \
docker network create network_$i \
&& docker volume create volume_$i \
&& docker run -d --name container_$i -v volume_$i:/volume busybox sh -c 'truncate -s 5M somefile; truncate -s 5M /volume/file' \
&& docker tag busybox:latest image_$i; \
done;
docker pull alpine
docker pull nginx:alpine
echo -e "FROM busybox\nRUN truncate -s 50M bigfile" | DOCKER_BUILDKIT=1 docker build -
Start listening for "prune" events in another shell:
docker events --filter event=prune
Prune containers, networks, volumes, and build-cache:
docker system prune -af --volumes
See the events that are returned:
docker events --filter event=prune
2020-07-25T12:12:09.268491000Z container prune (reclaimed=15728640)
2020-07-25T12:12:09.447890400Z network prune (reclaimed=0)
2020-07-25T12:12:09.452323000Z volume prune (reclaimed=15728640)
2020-07-25T12:12:09.517236200Z image prune (reclaimed=21568540)
2020-07-25T12:12:09.566662600Z builder prune (reclaimed=52428841)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-07-25 08:14:38 -04:00
|
|
|
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
|
2017-04-13 14:37:32 -04:00
|
|
|
}
|
|
|
|
|
2019-04-02 00:08:51 -04:00
|
|
|
// RegisterGRPC registers buildkit controller to the grpc server.
|
|
|
|
func (b *Backend) RegisterGRPC(s *grpc.Server) {
|
|
|
|
if b.buildkit != nil {
|
|
|
|
b.buildkit.RegisterGRPC(s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-13 14:37:32 -04:00
|
|
|
// Build builds an image from a Source
|
|
|
|
func (b *Backend) Build(ctx context.Context, config backend.BuildConfig) (string, error) {
|
|
|
|
options := config.Options
|
2018-05-18 01:47:34 -04:00
|
|
|
useBuildKit := options.Version == types.BuilderBuildKit
|
2018-04-17 18:50:17 -04:00
|
|
|
|
2017-04-13 14:37:32 -04:00
|
|
|
tagger, err := NewTagger(b.imageComponent, config.ProgressWriter.StdoutFormatter, options.Tags)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2018-04-17 18:50:17 -04:00
|
|
|
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
|
|
|
|
}
|
2017-04-13 14:37:32 -04:00
|
|
|
}
|
|
|
|
|
2018-05-18 20:50:52 -04:00
|
|
|
if build == nil {
|
|
|
|
return "", nil
|
|
|
|
}
|
|
|
|
|
2017-04-13 14:37:32 -04:00
|
|
|
var imageID = build.ImageID
|
|
|
|
if options.Squash {
|
|
|
|
if imageID, err = squashBuild(build, b.imageComponent); err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
2017-06-26 07:54:09 -04:00
|
|
|
if config.ProgressWriter.AuxFormatter != nil {
|
2018-06-11 14:48:42 -04:00
|
|
|
if err = config.ProgressWriter.AuxFormatter.Emit("moby.image.id", types.BuildResult{ID: imageID}); err != nil {
|
2017-06-26 07:54:09 -04:00
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
}
|
2017-04-13 14:37:32 -04:00
|
|
|
}
|
|
|
|
|
2018-04-19 14:08:33 -04:00
|
|
|
if !useBuildKit {
|
|
|
|
stdout := config.ProgressWriter.StdoutFormatter
|
|
|
|
fmt.Fprintf(stdout, "Successfully built %s\n", stringid.TruncateID(imageID))
|
|
|
|
}
|
2019-06-03 18:34:13 -04:00
|
|
|
if imageID != "" {
|
|
|
|
err = tagger.TagImages(image.ID(imageID))
|
|
|
|
}
|
2017-04-13 14:37:32 -04:00
|
|
|
return imageID, err
|
|
|
|
}
|
|
|
|
|
2017-05-15 17:54:27 -04:00
|
|
|
// PruneCache removes all cached build sources
|
2018-08-15 17:24:37 -04:00
|
|
|
func (b *Backend) PruneCache(ctx context.Context, opts types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error) {
|
2019-09-24 17:37:38 -04:00
|
|
|
buildCacheSize, cacheIDs, err := b.buildkit.Prune(ctx, opts)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "failed to prune build cache")
|
2017-05-15 17:54:27 -04:00
|
|
|
}
|
API: add "prune" events
This patch adds a new "prune" event type to indicate that pruning of a resource
type completed.
This event-type can be used on systems that want to perform actions after
resources have been cleaned up. For example, Docker Desktop performs an fstrim
after resources are deleted (https://github.com/linuxkit/linuxkit/tree/v0.7/pkg/trim-after-delete).
While the current (remove, destroy) events can provide information on _most_
resources, there is currently no event triggered after the BuildKit build-cache
is cleaned.
Prune events have a `reclaimed` attribute, indicating the amount of space that
was reclaimed (in bytes). The attribute can be used, for example, to use as a
threshold for performing fstrim actions. Reclaimed space for `network` events
will always be 0, but the field is added to be consistent with prune events for
other resources.
To test this patch:
Create some resources:
for i in foo bar baz; do \
docker network create network_$i \
&& docker volume create volume_$i \
&& docker run -d --name container_$i -v volume_$i:/volume busybox sh -c 'truncate -s 5M somefile; truncate -s 5M /volume/file' \
&& docker tag busybox:latest image_$i; \
done;
docker pull alpine
docker pull nginx:alpine
echo -e "FROM busybox\nRUN truncate -s 50M bigfile" | DOCKER_BUILDKIT=1 docker build -
Start listening for "prune" events in another shell:
docker events --filter event=prune
Prune containers, networks, volumes, and build-cache:
docker system prune -af --volumes
See the events that are returned:
docker events --filter event=prune
2020-07-25T12:12:09.268491000Z container prune (reclaimed=15728640)
2020-07-25T12:12:09.447890400Z network prune (reclaimed=0)
2020-07-25T12:12:09.452323000Z volume prune (reclaimed=15728640)
2020-07-25T12:12:09.517236200Z image prune (reclaimed=21568540)
2020-07-25T12:12:09.566662600Z builder prune (reclaimed=52428841)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-07-25 08:14:38 -04:00
|
|
|
b.eventsService.Log("prune", events.BuilderEventType, events.Actor{
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"reclaimed": strconv.FormatInt(buildCacheSize, 10),
|
|
|
|
},
|
|
|
|
})
|
2019-09-24 17:37:38 -04:00
|
|
|
return &types.BuildCachePruneReport{SpaceReclaimed: uint64(buildCacheSize), CachesDeleted: cacheIDs}, nil
|
2017-05-15 17:54:27 -04:00
|
|
|
}
|
|
|
|
|
2018-05-23 18:53:14 -04:00
|
|
|
// Cancel cancels the build by ID
|
2018-04-19 14:08:33 -04:00
|
|
|
func (b *Backend) Cancel(ctx context.Context, id string) error {
|
|
|
|
return b.buildkit.Cancel(ctx, id)
|
|
|
|
}
|
|
|
|
|
2017-04-13 14:37:32 -04:00
|
|
|
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
|
|
|
|
}
|