# Buildkit on Windows Anthony Nandaa, 2023/24 ## TODO > This is a draft area for my todo's, not all of them. - [ ] Set up a build pipeline for e2e testing for WCOW buildkit (on AzDO) - [ ] Craft the current issues identified into specific issue on `moby/buildkit` and link them. Add `help needed` tag where possible. - [ ] Fuzz a few dockerfiles for testing, using GPT. (Later on, can see if this can be part of our e2e workflow). - [ ] Revisit to close issue [`buildkit#616`](https://github.com/moby/buildkit/issues/616) ## Integration Tests ## Cheatsheet - Busybox for Windows: `registry.k8s.io/e2e-test-images/busybox:1.29-2` - Sample test: ```bash go test --test.run=TestIntegration/TestImageManifestRegistryCacheImportExport/worker=container ``` - Debugging with Delve ```bash dlv test -- --test.run=TestIntegration/TestImageManifestRegistryCacheImportExport/worker=container ``` ### `/client` - `client/client_test.go testExportedImageLabels` - patch: [test-export-image-labels.patch](https://github.com/moby/buildkit/files/13725388/test-export-image-labels.patch) - run log: https://paste.opensuse.org/pastes/9af7210bd8b5 - `testCacheExportCacheKeyLoop`: - run log: [client-272.txt](https://github.com/moby/buildkit/files/13725685/client-272.txt) - code changes, alpine -> busybox - > To be continued ## Issues that need investigation > This is a working area for the issues before opening them on `moby/buildkit`. > Or for collaborative investigation. ### Access Issues for `ContainerUser` in Root (WS2019) PS C:\Users\Administrator\sample_dockerfile> Set-Content Dockerfile @" >> FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 >> RUN mkdir hello >> COPY hello.txt C:/hello/hello.txt >> RUN echo "Goodbye!" >> C:/hello/hello.txt >> CMD ["cmd", "/C", "type C:\\hello\\hello.txt"] >> "@ PS C:\Users\Administrator\sample_dockerfile> docker build --no-cache -t hello-buildkit:docker . Sending build context to Docker daemon 3.072kB Step 1/5 : FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 ---> 6ad91fb31728 Step 2/5 : RUN mkdir hello ---> Running in 83274caa0797 Removing intermediate container 83274caa0797 ---> 1af3e89e5d1e Step 3/5 : COPY hello.txt C:/hello/hello.txt ---> 24baa07e955e Step 4/5 : RUN echo "Goodbye!" >> C:/hello/hello.txt ---> Running in cac8679cf3d6 Access is denied. The command 'cmd /S /C echo "Goodbye!" >> C:/hello/hello.txt' returned a non-zero code: 1 > TODO: try to run the same command with `docker` un-elevated to prove ACL enforcement. ### Slashes in `COPY` stanza → #9646 Verify if it's really a regression since `docker build` throws an error too, until you use front-slashes `/`: ``` Step 3/5 : COPY hello.txt C:\hello\hello.txt failed to copy files: failed to copy file: mkdir \\?\Volume{099f2dd8-e06c-4d8b-ae43-501351a34f93}\C:.: The directory name is invalid. ``` ### `CMD` stanza ignored? Cross-check why `CMD` is not run: ```powershell PS C:\dev\play\dockerfiles\hello_world2> buildctl build ` >> --frontend=dockerfile.v0 ` >> --local context=. \ ` >> --local dockerfile=. ` >> --output type=image,name=docker.io/0x/hello-buildkit,push=false [+] Building 8.3s (8/8) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 183B 0.0s => [internal] load metadata for mcr.microsoft.com/windows/nanoserver:ltsc2022 1.8s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build context 0.1s => => transferring context: 133B 0.0s => CACHED [1/3] FROM mcr.microsoft.com/windows/nanoserver:ltsc2022@sha256:64b22e42a69ebcdb86e49bf50780b64156431a50 0.1s => => resolve mcr.microsoft.com/windows/nanoserver:ltsc2022@sha256:64b22e42a69ebcdb86e49bf50780b64156431a508f7f06a 0.1s => [2/3] COPY hello.txt C:/ 0.3s => [3/3] RUN echo "Goodbye!" >> hello.txt 2.2s => exporting to image 3.5s => => exporting layers 3.4s => => exporting manifest sha256:e254603715df63e0d32a1328ee08da269c403717774a298189cc9c247b4f2153 0.0s => => exporting config sha256:2e98fcffba00eace82265deddcc90a8302cfaa90f504bc97239678b04cd5495c 0.0s => => naming to docker.io/0x/hello-buildkit 0.0s PS C:\dev\play\dockerfiles\hello_world2> docker build -t hello-bk-repro . Sending build context to Docker daemon 3.072kB Step 1/4 : FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 ---> 0db1879370e5 Step 2/4 : COPY hello.txt C:/ ---> 3e4e63e377c9 Step 3/4 : RUN echo "Goodbye!" >> hello.txt ---> Running in 2da1134ae39f Removing intermediate container 2da1134ae39f ---> 95ed8d34843b Step 4/4 : CMD ["cmd", "/C", "type C:\\hello.txt"] ---> Running in 47c679c37da7 Removing intermediate container 47c679c37da7 ---> 1e4d61ff9ef1 Successfully built 1e4d61ff9ef1 Successfully tagged hello-bk-repro:latest ``` ### Displaying of `\` in the progress texts (it’s stripped off) TBD ### `Access Denied` issue for items at the root **Repro:** - Follow the current example at [docs/windows.md]() - Using WS2022 You end up with: ``` PS C:\Users\Administrator\sample_dockerfile> buildctl build ` >> --frontend=dockerfile.v0 ` >> --local context=. \ ` >> --local dockerfile=. ` >> --output type=image,name=docker.io/<your_username>/hello-buildkit,push=true [+] Building 16.0s (7/7) FINISHED => [internal] load build definition from Dockerfile 0.1s => => transferring dockerfile: 183B 0.0s => [internal] load metadata for mcr.microsoft.com/windows/nanoserver:ltsc2022 0.5s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build context 0.2s => => transferring context: 133B 0.0s => [1/3] FROM mcr.microsoft.com/windows/nanoserver:ltsc2022@sha256:64b22e42a69ebcdb86e49bf50780b64156431a508f7f06ac3050c71920fe57b7 12.4s => => resolve mcr.microsoft.com/windows/nanoserver:ltsc2022@sha256:64b22e42a69ebcdb86e49bf50780b64156431a508f7f06ac3050c71920fe57b7 0.1s => => sha256:0de484043f1248d5382233de81d1687426c4c64b6507d0f768eff763724f1bac 116.97MB / 116.97MB 2.5s => => extracting sha256:0de484043f1248d5382233de81d1687426c4c64b6507d0f768eff763724f1bac 9.7s => [2/3] COPY hello.txt C:/ 0.3s => ERROR [3/3] RUN echo "Goodbye!" >> hello.txt 2.4s ------ > [3/3] RUN echo "Goodbye!" >> hello.txt: 1.949 Access is denied. ------ Dockerfile:3 -------------------- 1 | FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 2 | COPY hello.txt C:/ 3 | >>> RUN echo "Goodbye!" >> hello.txt 4 | CMD ["cmd", "/C", "type C:\\hello.txt"] 5 | -------------------- error: failed to solve: process "cmd /S /C echo \"Goodbye!\" >> hello.txt" did not complete successfully: exit code: 1 ``` **This is not a regression:** `docker build` also handles it in the same way: ``` PS > docker build -t hello-buildkit:docker . Sending build context to Docker daemon 3.072kB Step 1/4 : FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 ltsc2022: Pulling from windows/nanoserver 0de484043f12: Pull complete Digest: sha256:64b22e42a69ebcdb86e49bf50780b64156431a508f7f06ac3050c71920fe57b7 Status: Downloaded newer image for mcr.microsoft.com/windows/nanoserver:ltsc2022 ---> 6ad91fb31728 Step 2/4 : COPY hello.txt C:/ ---> 652f89575cdf Step 3/4 : RUN echo "Goodbye!" >> hello.txt ---> Running in 0540aad493a7 Access is denied. The command 'cmd /S /C echo "Goodbye!" >> hello.txt' returned a non-zero code: 1 ``` **Fix:** **Option 1:** - Add `USER ContainerAdministrator` to the dockerfile, since the default user is a low-priv `ContainerUser`: ```powershell Set-Content Dockerfile @" FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 USER ContainerAdministrator COPY hello.txt C:/ RUN echo "Goodbye!" >> hello.txt CMD ["cmd", "/C", "type C:\\hello.txt"] "@ ``` **Option 2:** - If you would like to maintain the low-priv, don't write to the root directory, butter anything inner (and not a system directory like `/windows`, etc). Therefore, we will modify the `dockerfile` to: ```powershell Set-Content Dockerfile @" FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 RUN mkdir hello COPY hello.txt C:/hello/hello.txt RUN echo "Goodbye!" >> hello\hello.txt CMD ["cmd", "/C", "type C:\\hello\\hello.txt"] "@