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) {
|
||||
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) {
|
||||
|
|
|
@ -53,7 +53,6 @@ func (s *composeService) Build(ctx context.Context, project *types.Project, opti
|
|||
}, s.stderr(), "Building")
|
||||
}
|
||||
|
||||
//nolint:gocyclo
|
||||
func (s *composeService) build(ctx context.Context, project *types.Project, options api.BuildOptions) (map[string]string, error) {
|
||||
args := options.Args.Resolve(envResolver(project.Environment))
|
||||
|
||||
|
@ -75,16 +74,6 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
|||
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 service.Build.Args == nil {
|
||||
service.Build.Args = args
|
||||
|
|
|
@ -18,6 +18,8 @@ package compose
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
|
@ -25,11 +27,13 @@ import (
|
|||
_ "github.com/docker/buildx/driver/docker-container" //nolint:blank-imports
|
||||
_ "github.com/docker/buildx/driver/kubernetes" //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/builder"
|
||||
"github.com/docker/buildx/util/dockerutil"
|
||||
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) {
|
||||
|
@ -43,23 +47,27 @@ func (s *composeService) doBuildBuildkit(ctx context.Context, opts map[string]bu
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Progress needs its own context that lives longer than the
|
||||
// build one otherwise it won't read all the messages from
|
||||
// build and will lock
|
||||
progressCtx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
w, err := xprogress.NewPrinter(progressCtx, s.stdout(), os.Stdout, mode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := build.Build(ctx, nodes, opts, dockerutil.NewClient(s.dockerCli), filepath.Dir(s.configFile().Filename), w)
|
||||
errW := w.Wait()
|
||||
if err == nil {
|
||||
err = errW
|
||||
}
|
||||
if err != nil {
|
||||
return nil, WrapCategorisedComposeError(err, BuildFailure)
|
||||
var response map[string]*client.SolveResponse
|
||||
if s.dryRun {
|
||||
response = s.dryRunBuildResponse(ctx, opts)
|
||||
} else {
|
||||
// Progress needs its own context that lives longer than the
|
||||
// build one otherwise it won't read all the messages from
|
||||
// build and will lock
|
||||
progressCtx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
w, err := xprogress.NewPrinter(progressCtx, s.stdout(), os.Stdout, mode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = build.Build(ctx, nodes, opts, dockerutil.NewClient(s.dockerCli), filepath.Dir(s.configFile().Filename), w)
|
||||
errW := w.Wait()
|
||||
if err == nil {
|
||||
err = errW
|
||||
}
|
||||
if err != nil {
|
||||
return nil, WrapCategorisedComposeError(err, BuildFailure)
|
||||
}
|
||||
}
|
||||
|
||||
imagesBuilt := map[string]string{}
|
||||
|
@ -76,3 +84,30 @@ func (s *composeService) doBuildBuildkit(ctx context.Context, opts map[string]bu
|
|||
|
||||
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