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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix various issues with the "make buildx" target #40089
Conversation
ping @cpuguy83 ptal |
Hm... interesting; am I dropping an env-var here, causing it to fall back to
|
2ba8476
to
3e455bd
Compare
Makefile
Outdated
@@ -35,6 +35,49 @@ export VALIDATE_REPO | |||
export VALIDATE_BRANCH | |||
export VALIDATE_ORIGIN_BRANCH | |||
|
|||
ifneq "$(strip $(shell command -v go 2>/dev/null))" "" |
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 all seems a bit overkill.
What are we trying to solve here?
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.
@cpuguy83 I ran into this problem;
/bin/sh: 4: go: not found
/bin/sh: 5: go: not found
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.
Likely because the GOOS
and GOARCH
make variables were not set
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.
Yeah but doesn't what we already have solve that? And in the case no go
the user just needs to set GOOS
and GOARCH
themselves.
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.
But I just discovered what the actual problem was; we were now actually using buildx v0.3.0, so it tried to pull an image that doesn't exist for s390x/power. The go not found
was (I think) just the output leaking from the go env GOHOSTOS || uname
line; I'll remove that one commit
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.
Oh, actually.. (sleepy head); it's because s390x/power are now using buildkit to build the image 馃
736c144
to
8f7be89
Compare
Yo, Jenkins, where did you go? edit: aaaaaaand he's back |
|
||
FROM golang:${GO_VERSION}-stretch | ||
COPY --from=build /usr/bin/buildx /usr/bin/buildx |
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.
Ah! 馃挕 I know why it failed in this branch; before this, there was no COPY
in the Dockerfile, and because the COPY
was added, it started downloading the docker.io/tonistiigi/copy:v0.1.3
image. Apparently, that one is only available for amd64 ?
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.
Yup; that one is only amd64, and armv7
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.
What's the reasoning for doing this second image?
This only produces a runnable image if the specified GOOS/GOARCH == the daemon's GOOS/GOARCH
In effect this is creating a 2nd image and taking even more space since buildx is duplicated.
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.
The first stage won't be tagged, so can be garbage collected, and only the second one is preserved; the final image is roughly 870MB whereas without that stage, we're tagging an image that's 1.71GB; see the commit message 39f1a4a
OK, this builds now, but I'll amend one commit message, and re-order commits (enabling BUILDX before the commit that adds the |
35a4447
to
c0d8ebf
Compare
Dockerfile.buildx
Outdated
RUN GOOS="${GOOS}" GOARCH="${GOARCH}" BUILDX_COMMIT="${BUILDX_COMMIT}" \ | ||
&& export version="$(git describe --tags)" \ |
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.
there should not be &&
in here as what is before (var assignments) is not a command.
Dockerfile.buildx
Outdated
RUN GOOS="${GOOS}" GOARCH="${GOARCH}" BUILDX_COMMIT="${BUILDX_COMMIT}" \ | ||
&& export version="$(git describe --tags)" \ | ||
&& export commit="$(git rev-parse --short HEAD)" \ |
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.
1 export
allows for multiple var assignments
2 you don't need to export any variables as you're using them only here ("export" means make them available for child processes, and I don't see how it's necessary here)
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.
Oh I see why you're using export... so you would use the vars later. Well, I still don't like the way it looks :(
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.
Let me try again; I think I tried without export, and for some reason, things failed.
Makefile
Outdated
--build-arg BUILDX_COMMIT \ | ||
--build-arg BUILDX_REPO \ | ||
--build-arg GOOS=$$(if [ -n "$(GOOS)" ]; then echo $(GOOS); else go env GOHOSTOS || uname | awk '{print tolower($$0)}' || true; fi) \ | ||
--build-arg GOARCH=$$(if [ -n "$(GOARCH)" ]; then echo $(GOARCH); else go env GOHOSTARCH || true; fi) \ | ||
. && \ | ||
id=$$(docker create moby-buildx:$(BUILDX_COMMIT)); \ | ||
if [ -n "$${id}" ]; then docker cp $${id}:/usr/bin/buildx $@ && touch $@; docker rm -f $${id}; fi | ||
id=$$(docker create moby-buildx:$${BUILDX_COMMIT:-latest}); \ |
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.
OK, so using &&
from makefile is redundant. If any command fails, make stops right there. I guess this practice comes from Dockerfile RUN
use, but makefile is different and if we can make things simpler, let's do it.
In other words,
docker build ....
id=$$(docker ...); if [ -n "$${id}" ]; ....
$@ version
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.
Ok I rewrote it a bit; also put the if
over a couple of lines, but let me know if that's too verbose.
c0d8ebf
to
0f01951
Compare
buildx: bundles/buildx # build buildx cli tool | ||
else | ||
buildx: | ||
buildx: bundles/buildx ## build buildx cli tool |
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.
In #40091 buildx is a required pre-req for all builds.
What happens if we don't define buildx:
?
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 should be covered by the .PHONY buildx
mkdir foo && cd foo
echo ".PHONY: buildx" > Makefile
make buildx
# make: Nothing to be done for `buildx'.
echo $?
# 0
make nonexistingtarget
# make: *** No rule to make target `nonexistingtarget'. Stop.
echo $?
# 2
Dockerfile.buildx
Outdated
-X \"github.com/docker/buildx/version.Revision=$(git rev-parse --short HEAD)\" \ | ||
-X \"github.com/docker/buildx/version.Package=github.com/docker/buildx\"" \ | ||
&& go build -ldflags "${ldflags}" -o /usr/bin/buildx ./cmd/buildx |
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 artificial here as we don't have any command to succeed before it.
I also see a repetition of github.com/docker/buildx
string; why don't we do this
pkg="github.com/docker/buildx"; \
ldflags=" \
-X \"${pkg}/version.Version=$(git describe --tags)\" \
-X \"${pkg}/version.Revision=$(git rev-parse --short HEAD)\" \
-X \"${pkg}/version.Package=${pkg}\" \
"; \
go build -ldflags "${ldflags}" -o /usr/bin/buildx ./cmd/buildx
I checked it works in both bash
and dash
, and even passes shellcheck
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 artificial here as we don't have any command to succeed before it.
arf. that's me messing up rebasing
I also see a repetition of github.com/docker/buildx string; why don't we do this
馃憤 yup, I like that
0f01951
to
ed69eae
Compare
Updated with the suggested changes |
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
ed69eae
to
182a02e
Compare
@kolyshkin updated 馃憤 |
-X \"${pkg}/version.Version=$(git describe --tags)\" \ | ||
-X \"${pkg}/version.Revision=$(git rev-parse --short HEAD)\" \ | ||
-X \"${pkg}/version.Package=buildx\" \ |
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.
hmm. shouldn't it be -X \"${pkg}/version.Package=${pkg}\" \
?
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.
See #40089 (comment)
This way, it looks like
buildx version
buildx v0.3.0 c967f1d
instead of
buildx version
github.com/docker/buildx v0.3.0 c967f1d
Commit 1be2cc2 updated the Makefile to force the use of BuildKit, if `USE_BUILDX` was not set. As a side-effect, Jenkins now started using BuildKit on s390x and ppc64le as well, because it overwrote the `DOCKER_BUILDKIT=0` that was set. This commit forces the use of buildx on s390x and ppc64le. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The variables were not substituted, because single-quotes were used. While at it; change the fixed version/commit to use the actual commit and version, using git. before this change: make buildx && ./bundles/buildx version github.com/docker/buildx ${BUILDX_COMMIT} ${BUILDX_COMMIT} after this change: make buildx && ./bundles/buildx version buildx v0.3.0 c967f1d Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The `BUILDX_COMMIT` variable was set as a Make variable, which isn't exported, and thus not available in scripts, unless referenced through `$(VAR)` (non-curly-brackets). As a result `--build-arg BUILDX_COMMIT` did not set the `BUILDX_COMMIT` build-arg, and the default from the Dockerfile (`master`) was used instead. This patch exports the default version that's set in the Makefile, so that it can be used as a regular environment variable. The script was also slighly modified to no longer use the `Make` variable. In addition, the `buildx` target now calls `buildx version`, which is useful to confirm if the binary was successfully built (and with the correct version). Before: rm -f bundles/buildx && make buildx && ./bundles/buildx version # => => naming to docker.io/library/moby-buildx:v0.3.0 github.com/docker/buildx v0.3.1 6db68d0 # using a make variable: rm -f bundles/buildx && make BUILDX_COMMIT=v0.2.1 buildx && ./bundles/buildx version # => => naming to docker.io/library/moby-buildx:v0.2.1 github.com/docker/buildx v0.3.1 6db68d0 # using an environment variable: rm -f bundles/buildx && BUILDX_COMMIT=v0.2.2 make buildx && ./bundles/buildx version # => => naming to docker.io/library/moby-buildx:v0.2.2 github.com/docker/buildx v0.3.1 6db68d0 After: # default rm -f bundles/buildx && make buildx # => => naming to docker.io/library/moby-buildx:v0.3.0 github.com/docker/buildx v0.3.0 c967f1d # using a make variable: rm -f bundles/buildx && make BUILDX_COMMIT=v0.2.1 buildx # => => naming to docker.io/library/moby-buildx:v0.2.1 github.com/docker/buildx v0.2.1 0eb2df5 # using an environment variable: rm -f bundles/buildx && BUILDX_COMMIT=v0.2.2 make buildx # => => naming to docker.io/library/moby-buildx:v0.2.2 github.com/docker/buildx v0.2.2 ab5fe3d Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This patch removes the `BUILDX_COMMIT` make variable. With the make variable removed, it no longer "masks" environment variables, and there is no longer a need to export the variable. A side effect of this change, is that (by default), the buildx image is tagged as `moby-buildx:latest`. This likely isn't a problem, because the build-cache would still be preserved in intermediate images. Having the image tagged as `:latest` also makes cleaning up easier (without having to remove the image for each version tagged. Otherwise, the behavior remains the same as before: # default rm -f bundles/buildx && make buildx # => => naming to docker.io/library/moby-buildx:latest github.com/docker/buildx v0.3.0 c967f1d # using a make variable: rm -f bundles/buildx && make BUILDX_COMMIT=v0.2.1 buildx # => => naming to docker.io/library/moby-buildx:v0.2.1 github.com/docker/buildx v0.2.1 0eb2df5 # using an environment variable: rm -f bundles/buildx && BUILDX_COMMIT=v0.2.2 make buildx # => => naming to docker.io/library/moby-buildx:v0.2.2 github.com/docker/buildx v0.2.2 ab5fe3d Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This simplifies the makefile a bit, while preserving the functionality. Using a non-existing Dockerfile to demonstrate: make buildx Successfully tagged moby-buildx:latest 92059305df7371f8b5b3638d4d405d49ff909031a7bc6d2f515cb0a0df03c2f4 github.com/docker/buildx v0.3.0 c967f1d make BUILDX_DOCKERFILE=foo buildx BUILDX_DOCKERFILE=foo buildx unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /Users/sebastiaan/go/src/github.com/docker/docker/foo: no such file or directory Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Un-indent the comment, so that it doesn't get printed by the shell script (moved it above the target, as it looked slightly less cluttered) Also fixed the "help" comment, so that it shows up in `make help`, and removed the un-needed dummy `buildx:` target. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The build-stage would still be in the local cache (and can be cleaned up with `docker system prune`) but the tagged image (which usually wouldn't be removed) will take up less space now. Note that - the binary is not statically linked, so we cannot use a "from scratch" image - in cases where the binary is cross-compiled (e.g. on a non-linux machine), the image itself is not really useful (we may want to consider not tagging the image in that situation) Before: REPOSITORY TAG IMAGE ID CREATED SIZE moby-buildx latest c9b2af465baf 7 minutes ago 1.71GB After: REPOSITORY TAG IMAGE ID CREATED SIZE moby-buildx latest 345501e2df0a 2 minutes ago 820MB Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
182a02e
to
7eb804c
Compare
rebased to kick CI (master was broken because of a linting issue) |
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
argh; failing on a flaky test;
|
relates to #39340 (and slightly related to #40088)
See individual commit messages for a description 馃槄