-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Support for experimental BuildKit #1111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
fc87eac to
61295de
Compare
simonferquel
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small nits, but overall seem ok :)
Makefile
Outdated
| vendor: vendor.conf ## check that vendor matches vendor.conf | ||
| rm -rf vendor | ||
| bash -c 'vndr |& grep -v -i clone' | ||
| bash -c 'vndr -verbose' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this change related to the PR?
cli/command/image/build/context.go
Outdated
| // If an archive is detected in the input stream, rc stream is non-nil and ready | ||
| // to be consumed in lieu of the input stream, and dockerfileDir is empty. | ||
| // | ||
| // If a Dockerfile is detected, rc is set to nil and dockerfileDir is set to a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment does not seem in sync
| // name specified by DefaultDockerfileName and returns the path to the | ||
| // temporary directory containing the Dockerfile. | ||
| func WriteTempDockerfile(rc io.ReadCloser) (dockerfileDir string, err error) { | ||
| dockerfileDir, err = ioutil.TempDir("", "docker-build-tempdockerfile-") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error management in this function seem more complicated than necessary. As the err output parameter is named, why not use a single defer block to centralize error reporting ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: consider renaming the err output var, to prevent it from being confused with local vars (we ran into a couple of cases where this was overlooked in code changes)
61295de to
b30095b
Compare
|
@simonferquel updated. Appreciate your review! |
cli/command/image/build/context.go
Outdated
| _, err = io.Copy(f, buf) | ||
| _, err = io.Copy(f, rc) | ||
| if err != nil { | ||
| f.Close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defer func (){
er := f.Close ()
if err == nil {
err = er
}
}
Not sure about it, but I dislike having duplicated Close call. Seem error prone if/when new code paths are introduced in the future.
b3864cd to
9961958
Compare
cli/command/image/build.go
Outdated
| flags.SetAnnotation("stream", "experimental", nil) | ||
| flags.SetAnnotation("stream", "version", []string{"1.31"}) | ||
|
|
||
| flags.BoolVar(&options.noConsole, "no-console", false, "Show non-console output") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe better to add "BuildKit mode only"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. BTW, the main reason we have this flag, is because the interactive output of buildkit doesn't show outputs of RUN commands. If it did, we might not need this flag. Which makes me wonder whether we could remove this flag in the future as it graduates from experimental. cc @tonistiigi @vdemeester
| // nolint: gocyclo | ||
| func runBuild(dockerCli command.Cli, options buildOptions) error { | ||
| if os.Getenv("DOCKER_BUILDKIT") != "" { | ||
| return runBuildBuildKit(dockerCli, options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason not to use CLI flag?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AkihiroSuda because in the future I'd like to remove it.
| // And build cache | ||
| fmt.Fprintf(ctx.Output, "\nBuild cache usage: %s\n\n", units.HumanSize(float64(ctx.BuilderSize))) | ||
|
|
||
| t := template.Must(template.New("buildcache").Parse(defaultBuildCacheVerboseFormat)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be only visible when the daemon is experimental right ?
9961958 to
ddc1763
Compare
Signed-off-by: Tonis Tiigi <[email protected]>
Signed-off-by: Tonis Tiigi <[email protected]>
Signed-off-by: Tonis Tiigi <[email protected]>
Signed-off-by: Tonis Tiigi <[email protected]>
Signed-off-by: Tibor Vass <[email protected]>
Signed-off-by: Tibor Vass <[email protected]>
…ile and context Signed-off-by: Tibor Vass <[email protected]>
ddc1763 to
9939444
Compare
vdemeester
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Design LGTM 👼
|
Ping @simonferquel if you have any further comments. |
|
Lgtm :) |
| if _, err := io.Copy(f, rc); err != nil { | ||
| return "", err | ||
| } | ||
| return dockerfileDir, rc.Close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If rc.Close() returns an error then the callers will leak tmpDir, since they don't clean it up in the error case (and it would be a little odd to expect them to do so).
The dir is also leaked on errors in in the os.Create above too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ijc Addressed.
cli/command/image/build_buildkit.go
Outdated
| remote = uploadRequestRemote | ||
| } else { | ||
| if options.dockerfileName != "" { | ||
| // This is new behavior, but @tiborvass believes it's correct. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a discussion for the commit message rather than a code comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ijc addressed in commit message.
f08a015 to
eb91ac0
Compare
This commit brings a more pedantic change in the following ambiguous case: cat Dockerfile | docker build -f otherDockerfile - The legacy builder does not error out and prefers the Dockerfile from stdin while the buildkit-based one errors out. Note that this is only in the case where stdin is a Dockerfile (not an archive) Signed-off-by: Tibor Vass <[email protected]>
With this patch the following become true even with buildkit enabled: 1. `docker build -q .` only outputs the created image's sha256 ID. 2. `docker build -q .` outputs as if no `-q` was specified, if error occurred 3. `docker build . &> out` outputs JSON (instead of TTY characters) Signed-off-by: Tibor Vass <[email protected]>
…string enables the use of buildkit Signed-off-by: Tibor Vass <[email protected]>
Signed-off-by: Tibor Vass <[email protected]>
…adable output with buildkit Unfortunately, this is for now the only way to see the output of RUN commands when using buildkit. It is equivalent to `DOCKER_BUILDKIT=1 docker build . 2>&1 | cat` Signed-off-by: Tibor Vass <[email protected]>
Signed-off-by: Tibor Vass <[email protected]>
Signed-off-by: Tibor Vass <[email protected]>
Signed-off-by: Tibor Vass <[email protected]>
Signed-off-by: Tonis Tiigi <[email protected]>
Signed-off-by: Tibor Vass <[email protected]>
Signed-off-by: Tibor Vass <[email protected]>
eb91ac0 to
00792d1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I created a local build using moby commit 692df46 for the engine and this PR's cli commit 00792d1. Stuff works when testing a build of docker-dev image from moby/moby repo:
$ DOCKER_BUILDKIT=1 docker build -t docker-dev .
[+] Building 124.1s (58/58) FINISHED
One issue to address for future before this goes out of experimental is to make sure the error message is nicer if the cli is talking to an older version of an engine that does not have buildkit:
$ DOCKER_BUILDKIT=1 docker build -t docker-dev .
Error response from daemon: failed to copy to /var/lib/docker/builder/e9f592f09a03f2584b07a250ec1dc3e46b0e580b9da7e311021d55a6c0b35f86: rpc error: code = Unknown desc = no access allowed to dir ""
Signed-off-by: Tibor Vass <[email protected]>
b1f3b4b to
5a103e1
Compare
|
FYI I changed |
thaJeztah
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left some questions / comments
cli/command/image/build_buildkit.go
Outdated
|
|
||
| // if span := opentracing.SpanFromContext(ctx); span != nil { | ||
| // statusContext = opentracing.ContextWithSpan(statusContext, span) | ||
| // } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be removed before merging?
| if cons, err := console.ConsoleFromFile(out); err == nil && (consoleOpt == nil || *consoleOpt) { | ||
| c = cons | ||
| } | ||
| // not using shared context to not disrupt display but let is finish reporting errors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: s/let is/let it/
cli/command/image/build_buildkit.go
Outdated
| } | ||
| // if options.quiet { | ||
| // fmt.Fprintf(dockerCli.Err(), "%s%s", progBuff, buildBuff) | ||
| // } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be removed before merging? (or a TODO added)
cli/command/formatter/disk_usage.go
Outdated
|
|
||
| func (c *diskUsageBuilderContext) Reclaimable() string { | ||
| return c.Size() | ||
| inUseBytes := int64(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var inUseBytes int64 ?
| // name specified by DefaultDockerfileName and returns the path to the | ||
| // temporary directory containing the Dockerfile. | ||
| func WriteTempDockerfile(rc io.ReadCloser) (dockerfileDir string, err error) { | ||
| dockerfileDir, err = ioutil.TempDir("", "docker-build-tempdockerfile-") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: consider renaming the err output var, to prevent it from being confused with local vars (we ran into a couple of cases where this was overlooked in code changes)
cli/command/image/build_buildkit.go
Outdated
| return errors.Errorf("buildkit not supported by daemon") | ||
| } | ||
|
|
||
| buildID := stringid.GenerateRandomID() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like this isn't used until quite some lines below; could you move this closer to where it's used?
cli/command/image/build_buildkit.go
Outdated
| // } | ||
| return cli.StatusError{Status: jerr.Message, StatusCode: jerr.Code} | ||
| } | ||
| return err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is redundant if you change the return below to return err.
perhaps changing the if err != nil to if err == nil above (and return early), could make the logic a bit less complicated
cli/command/image/build_buildkit.go
Outdated
|
|
||
| func resetUIDAndGID(s *fsutil.Stat) bool { | ||
| s.Uid = uint32(0) | ||
| s.Gid = uint32(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the type conversion needed here? (just wondering)
| func resetUIDAndGID(s *fsutil.Stat) bool { | ||
| s.Uid = uint32(0) | ||
| s.Gid = uint32(0) | ||
| return true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was wondering why the boolean return was here, but guess this is to satisfy an interface? (reading from my phone so couldn't check easily)
| if err := json.Unmarshal(*msg.Aux, &dt); err != nil { | ||
| return | ||
| } | ||
| if err := (&resp).Unmarshal(dt); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's ok to hide them actual errors? May be good to document that (as a comment here and/or godoc on the function)
|
@thaJeztah updated |
Signed-off-by: Tibor Vass <[email protected]>
913405f to
b3a5c15
Compare
thaJeztah
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
visually LGTM, but away from keyboard 😅
we'll need some documentation follow up likely
| // name specified by DefaultDockerfileName and returns the path to the | ||
| // temporary directory containing the Dockerfile. | ||
| func WriteTempDockerfile(rc io.ReadCloser) (dockerfileDir string, err error) { | ||
| // err is a named return value, due to the defer call below. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was thinking naming it retErr (eg), but just a nit; no need to change
|
LGTM |
This PR makes
docker builduse the experimental support in moby/moby#37151 when theDOCKER_BUILDKITenvironment variable is set.This is still a work in progress.
To test it, build the docker CLI from this PR, and use it with the engine built from moby/moby#37151.
Mainly looking for UX feedback and bad bugs.
The output of the builder is changing (using that of buildkit for interactive mode). Non-interactive output is currently JSON stream for now but it will likely evolve to a more human-readable output (the challenge being handling output of parallel RUN commands).
Known issues:
--iidfile(coming soon)Ping @tonistiigi @thaJeztah @vdemeester @garethr