Skip to content

Commit 260f1db

Browse files
committed
cli/command/image: move build-context detection to build
Removes direct imports of github.com/docker/docker/builder in the image package, to be moved later. Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent d8089e7 commit 260f1db

File tree

2 files changed

+71
-36
lines changed

2 files changed

+71
-36
lines changed

cli/command/image/build.go

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828
buildtypes "github.com/docker/docker/api/types/build"
2929
"github.com/docker/docker/api/types/container"
3030
registrytypes "github.com/docker/docker/api/types/registry"
31-
"github.com/docker/docker/builder/remotecontext/urlutil"
3231
"github.com/docker/docker/pkg/progress"
3332
"github.com/docker/docker/pkg/streamformatter"
3433
"github.com/moby/go-archive"
@@ -76,12 +75,6 @@ func (o buildOptions) dockerfileFromStdin() bool {
7675
return o.dockerfileName == "-"
7776
}
7877

79-
// contextFromStdin returns true when the user specified that the build context
80-
// should be read from stdin
81-
func (o buildOptions) contextFromStdin() bool {
82-
return o.context == "-"
83-
}
84-
8578
func newBuildOptions() buildOptions {
8679
ulimits := make(map[string]*container.Ulimit)
8780
return buildOptions{
@@ -189,21 +182,24 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
189182
buildCtx io.ReadCloser
190183
dockerfileCtx io.ReadCloser
191184
contextDir string
192-
tempDir string
193185
relDockerfile string
194186
progBuff io.Writer
195187
buildBuff io.Writer
196188
remote string
197189
)
198190

191+
contextType, err := build.DetectContextType(options.context)
192+
if err != nil {
193+
return err
194+
}
195+
199196
if options.dockerfileFromStdin() {
200-
if options.contextFromStdin() {
197+
if contextType == build.ContextTypeStdin {
201198
return errors.New("invalid argument: can't use stdin for both build context and dockerfile")
202199
}
203200
dockerfileCtx = dockerCli.In()
204201
}
205202

206-
specifiedContext := options.context
207203
progBuff = dockerCli.Out()
208204
buildBuff = dockerCli.Out()
209205
if options.quiet {
@@ -217,38 +213,43 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
217213
}
218214
}
219215

220-
switch {
221-
case options.contextFromStdin():
216+
switch contextType {
217+
case build.ContextTypeStdin:
222218
// buildCtx is tar archive. if stdin was dockerfile then it is wrapped
223219
buildCtx, relDockerfile, err = build.GetContextFromReader(dockerCli.In(), options.dockerfileName)
224-
case isLocalDir(specifiedContext):
225-
contextDir, relDockerfile, err = build.GetContextFromLocalDir(specifiedContext, options.dockerfileName)
226-
if err == nil && strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
220+
if err != nil {
221+
return fmt.Errorf("unable to prepare context from STDIN: %w", err)
222+
}
223+
case build.ContextTypeLocal:
224+
contextDir, relDockerfile, err = build.GetContextFromLocalDir(options.context, options.dockerfileName)
225+
if err != nil {
226+
return errors.Errorf("unable to prepare context: %s", err)
227+
}
228+
if strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
227229
// Dockerfile is outside of build-context; read the Dockerfile and pass it as dockerfileCtx
228230
dockerfileCtx, err = os.Open(options.dockerfileName)
229231
if err != nil {
230232
return errors.Errorf("unable to open Dockerfile: %v", err)
231233
}
232234
defer dockerfileCtx.Close()
233235
}
234-
case urlutil.IsGitURL(specifiedContext):
235-
tempDir, relDockerfile, err = build.GetContextFromGitURL(specifiedContext, options.dockerfileName)
236-
case urlutil.IsURL(specifiedContext):
237-
buildCtx, relDockerfile, err = build.GetContextFromURL(progBuff, specifiedContext, options.dockerfileName)
238-
default:
239-
return errors.Errorf("unable to prepare context: path %q not found", specifiedContext)
240-
}
241-
242-
if err != nil {
243-
if options.quiet && urlutil.IsURL(specifiedContext) {
244-
_, _ = fmt.Fprintln(dockerCli.Err(), progBuff)
236+
case build.ContextTypeGit:
237+
var tempDir string
238+
tempDir, relDockerfile, err = build.GetContextFromGitURL(options.context, options.dockerfileName)
239+
if err != nil {
240+
return errors.Errorf("unable to prepare context: %s", err)
245241
}
246-
return errors.Errorf("unable to prepare context: %s", err)
247-
}
248-
249-
if tempDir != "" {
250-
defer os.RemoveAll(tempDir)
242+
defer func() {
243+
_ = os.RemoveAll(tempDir)
244+
}()
251245
contextDir = tempDir
246+
case build.ContextTypeRemote:
247+
buildCtx, relDockerfile, err = build.GetContextFromURL(progBuff, options.context, options.dockerfileName)
248+
if err != nil && options.quiet {
249+
_, _ = fmt.Fprintln(dockerCli.Err(), progBuff)
250+
}
251+
default:
252+
return errors.Errorf("unable to prepare context: path %q not found", options.context)
252253
}
253254

254255
// read from a directory into tar archive
@@ -415,11 +416,6 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
415416
return nil
416417
}
417418

418-
func isLocalDir(c string) bool {
419-
_, err := os.Stat(c)
420-
return err == nil
421-
}
422-
423419
type translatorFunc func(context.Context, reference.NamedTagged) (reference.Canonical, error)
424420

425421
// validateTag checks if the given image name can be resolved.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package build
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/docker/docker/builder/remotecontext/urlutil"
8+
)
9+
10+
// ContextType describes the type (source) of build-context specified.
11+
type ContextType string
12+
13+
const (
14+
ContextTypeStdin ContextType = "stdin" // ContextTypeStdin indicates that the build-context is a TAR archive passed through STDIN.
15+
ContextTypeLocal ContextType = "local" // ContextTypeLocal indicates that the build-context is a local directory.
16+
ContextTypeRemote ContextType = "remote" // ContextTypeRemote indicates that the build-context is a remote URL.
17+
ContextTypeGit ContextType = "git" // ContextTypeGit indicates that the build-context is a GIT URL.
18+
)
19+
20+
// DetectContextType detects the type (source) of the build-context.
21+
func DetectContextType(specifiedContext string) (ContextType, error) {
22+
switch {
23+
case specifiedContext == "-":
24+
return ContextTypeStdin, nil
25+
case isLocalDir(specifiedContext):
26+
return ContextTypeLocal, nil
27+
case urlutil.IsGitURL(specifiedContext):
28+
return ContextTypeGit, nil
29+
case urlutil.IsURL(specifiedContext):
30+
return ContextTypeRemote, nil
31+
default:
32+
return "", fmt.Errorf("unable to prepare context: path %q not found", specifiedContext)
33+
}
34+
}
35+
36+
func isLocalDir(c string) bool {
37+
_, err := os.Stat(c)
38+
return err == nil
39+
}

0 commit comments

Comments
 (0)