mirror of https://github.com/docker/compose.git
cli: dry run support for `build` (#10502)
* add dry-run support for classic builder * add dry-run support for buildkit Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
This commit is contained in:
parent
03f4c0e631
commit
eca1365d42
|
@ -165,7 +165,20 @@ func (d *DryRunClient) CopyToContainer(ctx context.Context, container, path stri
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DryRunClient) ImageBuild(ctx context.Context, reader io.Reader, options moby.ImageBuildOptions) (moby.ImageBuildResponse, error) {
|
func (d *DryRunClient) ImageBuild(ctx context.Context, reader io.Reader, options moby.ImageBuildOptions) (moby.ImageBuildResponse, error) {
|
||||||
return moby.ImageBuildResponse{}, ErrNotImplemented
|
jsonMessage, err := json.Marshal(&jsonmessage.JSONMessage{
|
||||||
|
Status: fmt.Sprintf("%[1]sSuccessfully built: dryRunID\n%[1]sSuccessfully tagged: %[2]s\n", DRYRUN_PREFIX, options.Tags[0]),
|
||||||
|
Progress: &jsonmessage.JSONProgress{},
|
||||||
|
ID: "",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return moby.ImageBuildResponse{}, err
|
||||||
|
}
|
||||||
|
rc := io.NopCloser(bytes.NewReader(jsonMessage))
|
||||||
|
|
||||||
|
return moby.ImageBuildResponse{
|
||||||
|
Body: rc,
|
||||||
|
OSType: "",
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DryRunClient) ImageInspectWithRaw(ctx context.Context, imageName string) (moby.ImageInspect, []byte, error) {
|
func (d *DryRunClient) ImageInspectWithRaw(ctx context.Context, imageName string) (moby.ImageInspect, []byte, error) {
|
||||||
|
|
|
@ -53,7 +53,6 @@ func (s *composeService) Build(ctx context.Context, project *types.Project, opti
|
||||||
}, s.stderr(), "Building")
|
}, s.stderr(), "Building")
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gocyclo
|
|
||||||
func (s *composeService) build(ctx context.Context, project *types.Project, options api.BuildOptions) (map[string]string, error) {
|
func (s *composeService) build(ctx context.Context, project *types.Project, options api.BuildOptions) (map[string]string, error) {
|
||||||
args := options.Args.Resolve(envResolver(project.Environment))
|
args := options.Args.Resolve(envResolver(project.Environment))
|
||||||
|
|
||||||
|
@ -75,16 +74,6 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO:glours - condition to be removed when dry-run support of build will be implemented.
|
|
||||||
if s.dryRun {
|
|
||||||
builder := "buildkit"
|
|
||||||
if !buildkitEnabled {
|
|
||||||
builder = "legacy builder"
|
|
||||||
}
|
|
||||||
fmt.Printf("%sBuilding image %s with %s\n", api.DRYRUN_PREFIX, service.Image, builder)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if !buildkitEnabled {
|
if !buildkitEnabled {
|
||||||
if service.Build.Args == nil {
|
if service.Build.Args == nil {
|
||||||
service.Build.Args = args
|
service.Build.Args = args
|
||||||
|
|
|
@ -18,6 +18,8 @@ package compose
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/sha1"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
@ -25,11 +27,13 @@ import (
|
||||||
_ "github.com/docker/buildx/driver/docker-container" //nolint:blank-imports
|
_ "github.com/docker/buildx/driver/docker-container" //nolint:blank-imports
|
||||||
_ "github.com/docker/buildx/driver/kubernetes" //nolint:blank-imports
|
_ "github.com/docker/buildx/driver/kubernetes" //nolint:blank-imports
|
||||||
_ "github.com/docker/buildx/driver/remote" //nolint:blank-imports
|
_ "github.com/docker/buildx/driver/remote" //nolint:blank-imports
|
||||||
|
"github.com/moby/buildkit/client"
|
||||||
|
|
||||||
"github.com/docker/buildx/build"
|
"github.com/docker/buildx/build"
|
||||||
"github.com/docker/buildx/builder"
|
"github.com/docker/buildx/builder"
|
||||||
"github.com/docker/buildx/util/dockerutil"
|
"github.com/docker/buildx/util/dockerutil"
|
||||||
xprogress "github.com/docker/buildx/util/progress"
|
xprogress "github.com/docker/buildx/util/progress"
|
||||||
|
"github.com/docker/compose/v2/pkg/progress"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *composeService) doBuildBuildkit(ctx context.Context, opts map[string]build.Options, mode string) (map[string]string, error) {
|
func (s *composeService) doBuildBuildkit(ctx context.Context, opts map[string]build.Options, mode string) (map[string]string, error) {
|
||||||
|
@ -43,23 +47,27 @@ func (s *composeService) doBuildBuildkit(ctx context.Context, opts map[string]bu
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Progress needs its own context that lives longer than the
|
var response map[string]*client.SolveResponse
|
||||||
// build one otherwise it won't read all the messages from
|
if s.dryRun {
|
||||||
// build and will lock
|
response = s.dryRunBuildResponse(ctx, opts)
|
||||||
progressCtx, cancel := context.WithCancel(context.Background())
|
} else {
|
||||||
defer cancel()
|
// Progress needs its own context that lives longer than the
|
||||||
w, err := xprogress.NewPrinter(progressCtx, s.stdout(), os.Stdout, mode)
|
// build one otherwise it won't read all the messages from
|
||||||
if err != nil {
|
// build and will lock
|
||||||
return nil, err
|
progressCtx, cancel := context.WithCancel(context.Background())
|
||||||
}
|
defer cancel()
|
||||||
|
w, err := xprogress.NewPrinter(progressCtx, s.stdout(), os.Stdout, mode)
|
||||||
response, err := build.Build(ctx, nodes, opts, dockerutil.NewClient(s.dockerCli), filepath.Dir(s.configFile().Filename), w)
|
if err != nil {
|
||||||
errW := w.Wait()
|
return nil, err
|
||||||
if err == nil {
|
}
|
||||||
err = errW
|
response, err = build.Build(ctx, nodes, opts, dockerutil.NewClient(s.dockerCli), filepath.Dir(s.configFile().Filename), w)
|
||||||
}
|
errW := w.Wait()
|
||||||
if err != nil {
|
if err == nil {
|
||||||
return nil, WrapCategorisedComposeError(err, BuildFailure)
|
err = errW
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, WrapCategorisedComposeError(err, BuildFailure)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
imagesBuilt := map[string]string{}
|
imagesBuilt := map[string]string{}
|
||||||
|
@ -76,3 +84,30 @@ func (s *composeService) doBuildBuildkit(ctx context.Context, opts map[string]bu
|
||||||
|
|
||||||
return imagesBuilt, err
|
return imagesBuilt, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s composeService) dryRunBuildResponse(ctx context.Context, options map[string]build.Options) map[string]*client.SolveResponse {
|
||||||
|
w := progress.ContextWriter(ctx)
|
||||||
|
buildResponse := map[string]*client.SolveResponse{}
|
||||||
|
for name, option := range options {
|
||||||
|
dryRunUUID := fmt.Sprintf("dryRun-%x", sha1.Sum([]byte(name)))
|
||||||
|
w.Event(progress.Event{
|
||||||
|
ID: " ",
|
||||||
|
Status: progress.Done,
|
||||||
|
Text: fmt.Sprintf("build service %s", name),
|
||||||
|
})
|
||||||
|
w.Event(progress.Event{
|
||||||
|
ID: "==>",
|
||||||
|
Status: progress.Done,
|
||||||
|
Text: fmt.Sprintf("==> writing image %s", dryRunUUID),
|
||||||
|
})
|
||||||
|
w.Event(progress.Event{
|
||||||
|
ID: "==> ==>",
|
||||||
|
Status: progress.Done,
|
||||||
|
Text: fmt.Sprintf(`naming to %s`, option.Tags[0]),
|
||||||
|
})
|
||||||
|
buildResponse[name] = &client.SolveResponse{ExporterResponse: map[string]string{
|
||||||
|
"containerimage.digest": dryRunUUID,
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
return buildResponse
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue