Open tomhoward87 opened 3 years ago
@TBBle ideas?
I can reproduce this, but only if I build with
docker build . --output .
If I have the Dockerfile somewhere else, I can run
docker build ..\context\ --output .
repeatedly, and it happily overwrites the file.
My guess is that the .git directory is being included in the context, carried through COPY . .
and COPY --from=base
, and is then trying to be written out in --output
, but cannot overwrite the file because it is read-only.
Before run:
C:\Users\paulh\bkbug\git
> ls -Recurse .\.git\objects\
Directory: C:\Users\paulh\bkbug\git\.git\objects
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 12/06/2021 4:00 PM 74
d---- 12/06/2021 4:00 PM info
d---- 12/06/2021 4:00 PM pack
Directory: C:\Users\paulh\bkbug\git\.git\objects\74
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar-- 12/06/2021 4:00 PM 119 bc6cf0dcb2d1f66ba26e6c32888a302240de3f
After run
C:\Users\paulh\bkbug\git
> ls -Recurse .\.git\objects\
Directory: C:\Users\paulh\bkbug\git\.git\objects
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 12/06/2021 4:01 PM 74
d---- 12/06/2021 4:00 PM info
d---- 12/06/2021 4:00 PM pack
Directory: C:\Users\paulh\bkbug\git\.git\objects\74
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar-- 12/06/2021 3:58 PM 0 .tmp.686810237
-ar-- 12/06/2021 4:00 PM 119 bc6cf0dcb2d1f66ba26e6c32888a302240de3f
It works if I create .dockerignore
.git
And it reproduces without git if I have separate context and output directories with the given Dockerfile, and have a read-only bla
in the latter:
> dir .\context\
Directory: C:\Users\paulh\bkbug\context
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 12/06/2021 3:52 PM 129 Dockerfile
> dir .\output\
Directory: C:\Users\paulh\bkbug\output
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar-- 12/06/2021 3:53 PM 4 bla
-a--- 12/06/2021 3:52 PM 0 Dockerfile
> docker build .\context\ --output .\output\
[+] Building 1.5s (10/10) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 32B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/alpine:3.13 1.3s
=> [internal] load build context 0.0s
=> => transferring context: 32B 0.0s
=> [base 1/4] FROM docker.io/library/alpine:3.13@sha256:69e70a79f2d41ab5d637de98c1e0b055206ba40a8145e7bddb55ccc04e13cf8f 0.0s
=> CACHED [base 2/4] WORKDIR /src 0.0s
=> CACHED [base 3/4] COPY . . 0.0s
=> CACHED [base 4/4] RUN echo "bla" >> /src/bla 0.0s
=> CACHED [end 1/1] COPY --from=base /src/ / 0.0s
=> ERROR exporting to client 0.0s
=> => copying files 52B 0.0s
------
> exporting to client:
------
error from receiver: failed to rename output\.tmp.832333578 to output\bla: rename output\.tmp.832333578 output\bla: Access is denied.
C:\Users\paulh\bkbug
> dir .\output\
Directory: C:\Users\paulh\bkbug\output
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 12/06/2021 3:53 PM 0 .tmp.832333578
-ar-- 12/06/2021 3:53 PM 4 bla
-a--- 12/06/2021 3:52 PM 0 Dockerfile
I'm not sure if --output
is supposed to successfully overwrite read-only files, though, so I don't know if this is user-error or a buildkit bug.
Apparently git objects are always read-only, so this shouldn't be a Windows-specific behaviour; so I'd guess that on Linux, BuildKit does overwrite the output files successfully, even if read-only.
It's also possible this is a problem due to interaction of read-only with the WSL2-based Docker setup, in which case it might be a Docker problem, rather than a BuildKit problem (or even a WSL2 problem...).
It's also possible that "rename over the top if a read-only file" is invalid as an operation on Windows, but valid on Linux, due to different permission semantics, and so we need to always unlink the target first (since we don't know this is Windows underneath in the context of BuildKit).
Apologies if this is the wrong place but I believe the issue lies with the output mode of buildkit on Windows when inside a git folder. I have made a simple Dockerfile that demonstrates the issue.
When I run
docker build . --output=.
the first time it runs with no issues, creating a file calledbla
.However if I run
git init
, thengit add Dockerfile
and try building again, I get the following error:This does not happen on other platforms, nor does it happen if the directory is not initialised for git or if git is initialised but no files have been added.