Search code examples
windowsdockermsys2

MSYS2 cannot delete file in Windows docker volume


I am experiencing an issue where MSYS2 running in docker can create and modify files in a mounted volume, but not delete them. This can be observed with commands where the deletion is explicit, such as rm a.txt, or with commands where the deletion is implicit, such as sed -i 's/foo/bar/' b.txt (b.txt should be edited in-place, and appears to be read, removed and recreated from the output (1)). The same files can be deleted with the equivalent DOS commands, such as del a.txt.

Using the following Dockerfile:

# Altered from https://github.com/StefanScherer/dockerfiles-windows/blob/main/msys2/Dockerfile
FROM mcr.microsoft.com/windows/servercore:20H2

RUN powershell -Command \
    $ProgressPreference = 'SilentlyContinue' ; \
    Write-Output 'Downloading msys2' ; \
    curl.exe -o msys2.tar.xy http://repo.msys2.org/distrib/msys2-x86_64-latest.tar.xz ; \
    Install-Package -Scope CurrentUser -Force 7Zip4Powershell ; \
    Write-Output 'Extracting tar.xz' ; \
    Expand-7zip msys2.tar.xy . ; \
    Write-Output 'Extracting tar' ; \
    Expand-7zip msys2.tar C:/ ; \
    Write-Output 'Done'

RUN powershell -Command \
    setx /M PATH $('C:\msys64\mingw64\bin;C:\msys64\usr\bin;C:\msys64\mingw32\bin;' + $Env:PATH)

Build and launch the container with:

docker pull mcr.microsoft.com/windows/servercore:20H2
docker build -t docker-msys .
mkdir local
docker run -ti -v "$(pwd)/local:C:/local" docker-msys cmd.exe

Using MSYS2 commands from within the container, lets manipulate files with:

touch a.txt
cp a.txt b.txt
rm a.txt
rm -f b.txt
ls *.txt

If launched from a non-mounted directory, the following is observed:

C:\>touch a.txt
C:\>cp a.txt b.txt
C:\>rm a.txt
C:\>rm -f b.txt
C:\>ls *.txt
ls: cannot access '*.txt': No such file or directory

Both files have been deleted as expected.

If launched from a mounted directory, here C:\local, the following is observed:

cd C:\local
C:\local>touch a.txt
C:\local>cp a.txt b.txt
C:\local>rm a.txt
rm: cannot remove 'a.txt': Invalid argument
C:\local>rm -f b.txt
C:\local>ls *.txt
a.txt  b.txt

Both files still remain.

Other MSYS commands will have unexpected behavior in the mounted directory:

C:\local>sed -i 's/foo/bar/' b.txt
sed: cannot remove ./sed7E6QmG: Invalid argument

The files can be removed from the mounted directory with the equivalent dos command:

C:\local>del /Q *

C:\local>dir
 Volume in drive C has no label.
 Volume Serial Number is 541F-A7C7

 Directory of C:\local

11/26/2020  04:05 PM    <DIR>          .
11/26/2020  04:05 PM    <DIR>          ..
               0 File(s)              0 bytes
               2 Dir(s)  48,827,674,624 bytes free

Changing from a mounted directory to a named volume affect in nothing the situation. The previous output is the same when the container is launched with:

docker volume create local-volume
docker run -ti -v local-volum:C:/local docker-msys cmd

The problem doesn't appear related to my Dockerfile. I was able to reproduce it using a container from https://hub.docker.com/r/mizarjp/winci-msys2 .

docker pull mizarjp/winci-msys2:1909
docker run -ti --rm -v "$(pwd)/local:C:/local" mizarjp/winci-msys2:1909 cmd.exe

Once in the container, perform set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\bin;C:\msys64\mingw32\bin;%PATH%; before repeating the previous tests to obtain the same results.

Finally, rather than installing MSYS2 inside docker, mounting it's directory inside a container produce the same situation.

Is there anything I am missing?

Details:

(1) My humble interpretation!


Solution

  • Adding --isolation=process fixed it. rm no longer fails for me!

    docker pull mcr.microsoft.com/windows/servercore:20H2
    docker build -t docker-msys .
    mkdir local
    docker run --rm -ti --isolation=process -v "$(pwd)/local:C:/local" docker-msys cmd.exe
    

    Re-running the previous commands produces:

    C:\>cd local
    C:\local>touch a.txt
    C:\local>cp a.txt b.txt
    C:\local>rm a.txt
    C:\local>rm -f b.txt
    C:\local>ls *.txt
    ls: cannot access '*.txt': No such file or directory