Skip to content
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

dockerfile: validate order when linking stages #4568

Merged
merged 1 commit into from
Jan 24, 2024

Conversation

tonistiigi
Copy link
Member

@tonistiigi tonistiigi commented Jan 19, 2024

Dockerfile stages always needed to be in order (you can not refer to a stage that is defined after your current command), but the behavior for incorrect order was undefined instead of consistently erroring.

Previously copying from a stage defined later would usually cause an error about a missing source file that could have been quite confusing. When the source path was "/" then the behavior could have been worse and resulted in COPY passing without error, without any files actually being copied (or only files from base image being copied).

This validates the order when on COPY and mount dispatch, returns proper error with correct source code location.

Dockerfile:5
--------------------
   3 |
   4 |     FROM busybox AS target
   5 | >>> COPY --from=build / /out
   6 |
   7 |     FROM alpine AS build
--------------------
error: failed to solve: cannot copy from stage "build", it needs to be defined before current stage "target"

@crazy-max
Copy link
Member

Nice! This will be easier to grasp.

This test seems to fail after this change when using implicit from?:

=== FAIL: frontend/dockerfile TestIntegration/TestMultiStageImplicitFrom/worker=containerd-rootless/frontend=client (0.62s)
    dockerfile_test.go:3694: 
        	Error Trace:	/src/frontend/dockerfile/dockerfile_test.go:3694
        	            				/src/util/testutil/integration/run.go:93
        	            				/src/util/testutil/integration/run.go:207
        	Error:      	Received unexpected error:
        	            	lstat /tmp/buildkit-mount4017488364/etc/passwd: no such file or directory
        	            	github.com/moby/buildkit/util/stack.Enable
        	            		/src/util/stack/stack.go:77
        	            	github.com/moby/buildkit/util/grpcerrors.FromGRPC
        	            		/src/util/grpcerrors/grpcerrors.go:198
        	            	github.com/moby/buildkit/util/grpcerrors.UnaryClientInterceptor
        	            		/src/util/grpcerrors/intercept.go:41
        	            	google.golang.org/grpc.(*ClientConn).Invoke
        	            		/src/vendor/google.golang.org/grpc/call.go:35
        	            	github.com/moby/buildkit/api/services/control.(*controlClient).Solve
        	            		/src/api/services/control/control.pb.go:2234
        	            	github.com/moby/buildkit/client.(*Client).solve.func2
        	            		/src/client/solve.go:274
        	            	golang.org/x/sync/errgroup.(*Group).Go.func1
        	            		/src/vendor/golang.org/x/sync/errgroup/errgroup.go:75
        	            	runtime.goexit
        	            		/usr/local/go/src/runtime/asm_amd64.s:1650
        	            	failed to solve
        	            	github.com/moby/buildkit/client.(*Client).solve.func2
        	            		/src/client/solve.go:290
        	            	golang.org/x/sync/errgroup.(*Group).Go.func1
        	            		/src/vendor/golang.org/x/sync/errgroup/errgroup.go:75
        	            	runtime.goexit
        	            		/usr/local/go/src/runtime/asm_amd64.s:1650

@tonistiigi tonistiigi force-pushed the dockerfile-detect-order branch 2 times, most recently from 20526af to 7c7f841 Compare January 20, 2024 00:27
Dockerfile stages always needed to be in order (you can not refer
to a stage that is defined after your current command), but the
behavior for incorrect order was undefined instead of consistently
erroring.

Previously copying from a stage defined later would usually cause
an error about a missing source file that could have been quite
confusing. When the source path was "/" then the behavior could have
been worse and resulted in COPY passing without error, without any
files actually being copied (or only images from base image being
copied).

This validates the order when on COPY and mount dispatch, returns
proper error with correct source code location.

Signed-off-by: Tonis Tiigi <[email protected]>
@crazy-max crazy-max added this to the v0.13.0 milestone Jan 22, 2024
@bperkins24
Copy link

This appears to have broken using a command like this in a base image:

ONBUILD RUN --mount=type=cache,target=/root/.cache/pip ...

When building the image referencing the base image, the error is failed to solve: cannot mount from stage "scratch" to "/root/.cache/pip", stage needs to be defined before current command

Pinning the Dockerfile referencing the base image to # syntax=docker/dockerfile:1.6 works but is not a viable long term solution. How do I go about submitting a bug report and getting this resolved?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants