Skip to content

Commit 30291ea

Browse files
committed
pkg/compose: align classic builder implementation with docker/cli
This aligns the implementation closer to the implementation in docker/cli, with the refactor done in [cli@260f1db]; this removes some direct uses of the github.com/docker/docker/builder/remotecontext/urlutil package, which won't be included in the new Moby modules. There's still some remaining uses in the `dockerFilePath` utility (which may need to be updated to also account for remote contexts that are not "git"), so possibly we can remove the use in that utility as well. [cli@260f1db]: docker/cli@260f1db Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent a03f256 commit 30291ea

File tree

2 files changed

+41
-36
lines changed

2 files changed

+41
-36
lines changed

pkg/compose/build_bake.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ func dockerFilePath(ctxName string, dockerfile string) string {
505505
if dockerfile == "" {
506506
return ""
507507
}
508+
// TODO(thaJeztah): remove uses of urlutil and only conditionally call this dockerFilePath utility
508509
if urlutil.IsGitURL(ctxName) {
509510
return dockerfile
510511
}

pkg/compose/build_classic.go

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import (
3434
buildtypes "github.com/docker/docker/api/types/build"
3535
"github.com/docker/docker/api/types/container"
3636
"github.com/docker/docker/api/types/registry"
37-
"github.com/docker/docker/builder/remotecontext/urlutil"
3837
"github.com/docker/docker/pkg/jsonmessage"
3938
"github.com/docker/docker/pkg/progress"
4039
"github.com/docker/docker/pkg/streamformatter"
@@ -48,17 +47,9 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
4847
buildCtx io.ReadCloser
4948
dockerfileCtx io.ReadCloser
5049
contextDir string
51-
tempDir string
5250
relDockerfile string
53-
54-
err error
5551
)
5652

57-
dockerfileName := dockerFilePath(service.Build.Context, service.Build.Dockerfile)
58-
specifiedContext := service.Build.Context
59-
progBuff := s.stdout()
60-
buildBuff := s.stdout()
61-
6253
if len(service.Build.Platforms) > 1 {
6354
return "", fmt.Errorf("the classic builder doesn't support multi-arch build, set DOCKER_BUILDKIT=1 to use BuildKit")
6455
}
@@ -80,34 +71,51 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
8071
}
8172
service.Build.Labels[api.ImageBuilderLabel] = "classic"
8273

83-
switch {
84-
case isLocalDir(specifiedContext):
74+
dockerfileName := dockerFilePath(service.Build.Context, service.Build.Dockerfile)
75+
specifiedContext := service.Build.Context
76+
progBuff := s.stdout()
77+
buildBuff := s.stdout()
78+
79+
contextType, err := build.DetectContextType(specifiedContext)
80+
if err != nil {
81+
return "", err
82+
}
83+
84+
switch contextType {
85+
case build.ContextTypeStdin:
86+
return "", fmt.Errorf("building from STDIN is not supported")
87+
case build.ContextTypeLocal:
8588
contextDir, relDockerfile, err = build.GetContextFromLocalDir(specifiedContext, dockerfileName)
86-
if err == nil && strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
87-
// Dockerfile is outside of build-context; read the Dockerfile and pass it as dockerfileCtx
89+
if err != nil {
90+
return "", fmt.Errorf("unable to prepare context: %s", err)
91+
}
92+
if strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
93+
// Dockerfile is outside build-context; read the Dockerfile and pass it as dockerfileCtx
8894
dockerfileCtx, err = os.Open(dockerfileName)
8995
if err != nil {
9096
return "", fmt.Errorf("unable to open Dockerfile: %w", err)
9197
}
9298
defer dockerfileCtx.Close() //nolint:errcheck
9399
}
94-
case urlutil.IsGitURL(specifiedContext):
100+
case build.ContextTypeGit:
101+
var tempDir string
95102
tempDir, relDockerfile, err = build.GetContextFromGitURL(specifiedContext, dockerfileName)
96-
case urlutil.IsURL(specifiedContext):
103+
if err != nil {
104+
return "", fmt.Errorf("unable to prepare context: %w", err)
105+
}
106+
defer func() {
107+
_ = os.RemoveAll(tempDir)
108+
}()
109+
contextDir = tempDir
110+
case build.ContextTypeRemote:
97111
buildCtx, relDockerfile, err = build.GetContextFromURL(progBuff, specifiedContext, dockerfileName)
112+
if err != nil {
113+
return "", fmt.Errorf("unable to prepare context: %w", err)
114+
}
98115
default:
99116
return "", fmt.Errorf("unable to prepare context: path %q not found", specifiedContext)
100117
}
101118

102-
if err != nil {
103-
return "", fmt.Errorf("unable to prepare context: %w", err)
104-
}
105-
106-
if tempDir != "" {
107-
defer os.RemoveAll(tempDir) //nolint:errcheck
108-
contextDir = tempDir
109-
}
110-
111119
// read from a directory into tar archive
112120
if buildCtx == nil {
113121
excludes, err := build.ReadDockerignore(contextDir)
@@ -125,7 +133,7 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
125133
excludes = build.TrimBuildFilesFromExcludes(excludes, relDockerfile, false)
126134
buildCtx, err = archive.TarWithOptions(contextDir, &archive.TarOptions{
127135
ExcludePatterns: excludes,
128-
ChownOpts: &archive.ChownOpts{},
136+
ChownOpts: &archive.ChownOpts{UID: 0, GID: 0},
129137
})
130138
if err != nil {
131139
return "", err
@@ -145,6 +153,7 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
145153
return "", err
146154
}
147155

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

@@ -166,16 +175,16 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
166175
RegistryToken: authConfig.RegistryToken,
167176
}
168177
}
169-
buildOptions := imageBuildOptions(s.dockerCli, project, service, options)
178+
buildOpts := imageBuildOptions(s.dockerCli, project, service, options)
170179
imageName := api.GetImageNameOrDefault(service, project.Name)
171-
buildOptions.Tags = append(buildOptions.Tags, imageName)
172-
buildOptions.Dockerfile = relDockerfile
173-
buildOptions.AuthConfigs = authConfigs
174-
buildOptions.Memory = options.Memory
180+
buildOpts.Tags = append(buildOpts.Tags, imageName)
181+
buildOpts.Dockerfile = relDockerfile
182+
buildOpts.AuthConfigs = authConfigs
183+
buildOpts.Memory = options.Memory
175184

176185
ctx, cancel := context.WithCancel(ctx)
177186
defer cancel()
178-
response, err := s.apiClient().ImageBuild(ctx, body, buildOptions)
187+
response, err := s.apiClient().ImageBuild(ctx, body, buildOpts)
179188
if err != nil {
180189
return "", err
181190
}
@@ -206,11 +215,6 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
206215
return imageID, nil
207216
}
208217

209-
func isLocalDir(c string) bool {
210-
_, err := os.Stat(c)
211-
return err == nil
212-
}
213-
214218
func imageBuildOptions(dockerCli command.Cli, project *types.Project, service types.ServiceConfig, options api.BuildOptions) buildtypes.ImageBuildOptions {
215219
config := service.Build
216220
return buildtypes.ImageBuildOptions{

0 commit comments

Comments
 (0)