Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pkg/compose/build_bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ import (
"github.com/containerd/errdefs"
"github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/image/build"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/progress"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/builder/remotecontext/urlutil"
"github.com/moby/buildkit/client"
gitutil "github.com/moby/buildkit/frontend/dockerfile/dfgitutil"
"github.com/moby/buildkit/util/progress/progressui"
Expand Down Expand Up @@ -505,7 +505,7 @@ func dockerFilePath(ctxName string, dockerfile string) string {
if dockerfile == "" {
return ""
}
if urlutil.IsGitURL(ctxName) {
if contextType, _ := build.DetectContextType(ctxName); contextType == build.ContextTypeGit {
return dockerfile
}
if !filepath.IsAbs(dockerfile) {
Expand Down
76 changes: 40 additions & 36 deletions pkg/compose/build_classic.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import (
buildtypes "github.com/docker/docker/api/types/build"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/builder/remotecontext/urlutil"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/streamformatter"
Expand All @@ -48,17 +47,9 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
buildCtx io.ReadCloser
dockerfileCtx io.ReadCloser
contextDir string
tempDir string
relDockerfile string

err error
)

dockerfileName := dockerFilePath(service.Build.Context, service.Build.Dockerfile)
specifiedContext := service.Build.Context
progBuff := s.stdout()
buildBuff := s.stdout()

if len(service.Build.Platforms) > 1 {
return "", fmt.Errorf("the classic builder doesn't support multi-arch build, set DOCKER_BUILDKIT=1 to use BuildKit")
}
Expand All @@ -80,34 +71,51 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
}
service.Build.Labels[api.ImageBuilderLabel] = "classic"

switch {
case isLocalDir(specifiedContext):
dockerfileName := dockerFilePath(service.Build.Context, service.Build.Dockerfile)
specifiedContext := service.Build.Context
progBuff := s.stdout()
buildBuff := s.stdout()

contextType, err := build.DetectContextType(specifiedContext)
if err != nil {
return "", err
}

switch contextType {
case build.ContextTypeStdin:
return "", fmt.Errorf("building from STDIN is not supported")
case build.ContextTypeLocal:
contextDir, relDockerfile, err = build.GetContextFromLocalDir(specifiedContext, dockerfileName)
if err == nil && strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
// Dockerfile is outside of build-context; read the Dockerfile and pass it as dockerfileCtx
if err != nil {
return "", fmt.Errorf("unable to prepare context: %w", err)
}
if strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
// Dockerfile is outside build-context; read the Dockerfile and pass it as dockerfileCtx
dockerfileCtx, err = os.Open(dockerfileName)
if err != nil {
return "", fmt.Errorf("unable to open Dockerfile: %w", err)
}
defer dockerfileCtx.Close() //nolint:errcheck
}
case urlutil.IsGitURL(specifiedContext):
case build.ContextTypeGit:
var tempDir string
tempDir, relDockerfile, err = build.GetContextFromGitURL(specifiedContext, dockerfileName)
case urlutil.IsURL(specifiedContext):
if err != nil {
return "", fmt.Errorf("unable to prepare context: %w", err)
}
defer func() {
_ = os.RemoveAll(tempDir)
}()
contextDir = tempDir
case build.ContextTypeRemote:
buildCtx, relDockerfile, err = build.GetContextFromURL(progBuff, specifiedContext, dockerfileName)
if err != nil {
return "", fmt.Errorf("unable to prepare context: %w", err)
}
default:
return "", fmt.Errorf("unable to prepare context: path %q not found", specifiedContext)
}

if err != nil {
return "", fmt.Errorf("unable to prepare context: %w", err)
}

if tempDir != "" {
defer os.RemoveAll(tempDir) //nolint:errcheck
contextDir = tempDir
}

// read from a directory into tar archive
if buildCtx == nil {
excludes, err := build.ReadDockerignore(contextDir)
Expand All @@ -125,7 +133,7 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
excludes = build.TrimBuildFilesFromExcludes(excludes, relDockerfile, false)
buildCtx, err = archive.TarWithOptions(contextDir, &archive.TarOptions{
ExcludePatterns: excludes,
ChownOpts: &archive.ChownOpts{},
ChownOpts: &archive.ChownOpts{UID: 0, GID: 0},
})
if err != nil {
return "", err
Expand All @@ -145,6 +153,7 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
return "", err
}

// Setup an upload progress bar
progressOutput := streamformatter.NewProgressOutput(progBuff)
body := progress.NewProgressReader(buildCtx, progressOutput, 0, "", "Sending build context to Docker daemon")

Expand All @@ -166,16 +175,16 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
RegistryToken: authConfig.RegistryToken,
}
}
buildOptions := imageBuildOptions(s.dockerCli, project, service, options)
buildOpts := imageBuildOptions(s.dockerCli, project, service, options)
imageName := api.GetImageNameOrDefault(service, project.Name)
buildOptions.Tags = append(buildOptions.Tags, imageName)
buildOptions.Dockerfile = relDockerfile
buildOptions.AuthConfigs = authConfigs
buildOptions.Memory = options.Memory
buildOpts.Tags = append(buildOpts.Tags, imageName)
buildOpts.Dockerfile = relDockerfile
buildOpts.AuthConfigs = authConfigs
buildOpts.Memory = options.Memory

ctx, cancel := context.WithCancel(ctx)
defer cancel()
response, err := s.apiClient().ImageBuild(ctx, body, buildOptions)
response, err := s.apiClient().ImageBuild(ctx, body, buildOpts)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -206,11 +215,6 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
return imageID, nil
}

func isLocalDir(c string) bool {
_, err := os.Stat(c)
return err == nil
}

func imageBuildOptions(dockerCli command.Cli, project *types.Project, service types.ServiceConfig, options api.BuildOptions) buildtypes.ImageBuildOptions {
config := service.Build
return buildtypes.ImageBuildOptions{
Expand Down