github.com/containerd/nerdctl@v1.7.7/cmd/nerdctl/container_run_mount_windows_test.go (about)

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  	"testing"
    23  
    24  	"github.com/containerd/nerdctl/pkg/inspecttypes/dockercompat"
    25  	"github.com/containerd/nerdctl/pkg/testutil"
    26  	"gotest.tools/v3/assert"
    27  )
    28  
    29  func TestRunMountVolume(t *testing.T) {
    30  	t.Parallel()
    31  	base := testutil.NewBase(t)
    32  	tID := testutil.Identifier(t)
    33  	rwDir, err := os.MkdirTemp(t.TempDir(), "rw")
    34  	if err != nil {
    35  		t.Fatal(err)
    36  	}
    37  	roDir, err := os.MkdirTemp(t.TempDir(), "ro")
    38  	if err != nil {
    39  		t.Fatal(err)
    40  	}
    41  	rwVolName := tID + "-rw"
    42  	roVolName := tID + "-ro"
    43  	for _, v := range []string{rwVolName, roVolName} {
    44  		defer base.Cmd("volume", "rm", "-f", v).Run()
    45  		base.Cmd("volume", "create", v).AssertOK()
    46  	}
    47  
    48  	containerName := tID
    49  	defer base.Cmd("rm", "-f", containerName).AssertOK()
    50  	base.Cmd("run",
    51  		"-d",
    52  		"--name", containerName,
    53  		"-v", fmt.Sprintf("%s:C:/mnt1", rwDir),
    54  		"-v", fmt.Sprintf("%s:C:/mnt2:ro", roDir),
    55  		"-v", fmt.Sprintf("%s:C:/mnt3", rwVolName),
    56  		"-v", fmt.Sprintf("%s:C:/mnt4:ro", roVolName),
    57  		testutil.CommonImage,
    58  		"ping localhost -t",
    59  	).AssertOK()
    60  
    61  	base.Cmd("exec", containerName, "cmd", "/c", "echo -n str1 > C:/mnt1/file1").AssertOK()
    62  	base.Cmd("exec", containerName, "cmd", "/c", "echo -n str2 > C:/mnt2/file2").AssertFail()
    63  	base.Cmd("exec", containerName, "cmd", "/c", "echo -n str3 > C:/mnt3/file3").AssertOK()
    64  	base.Cmd("exec", containerName, "cmd", "/c", "echo -n str4 > C:/mnt4/file4").AssertFail()
    65  	base.Cmd("rm", "-f", containerName).AssertOK()
    66  
    67  	base.Cmd("run",
    68  		"--rm",
    69  		"-v", fmt.Sprintf("%s:C:/mnt1", rwDir),
    70  		"-v", fmt.Sprintf("%s:C:/mnt3", rwVolName),
    71  		testutil.CommonImage,
    72  		"cat", "C:/mnt1/file1", "C:/mnt3/file3",
    73  	).AssertOutContainsAll("str1", "str3")
    74  	base.Cmd("run",
    75  		"--rm",
    76  		"-v", fmt.Sprintf("%s:C:/mnt3/mnt1", rwDir),
    77  		"-v", fmt.Sprintf("%s:C:/mnt3", rwVolName),
    78  		testutil.CommonImage,
    79  		"cat", "C:/mnt3/mnt1/file1", "C:/mnt3/file3",
    80  	).AssertOutContainsAll("str1", "str3")
    81  }
    82  
    83  func TestRunMountVolumeInspect(t *testing.T) {
    84  	base := testutil.NewBase(t)
    85  	testContainer := testutil.Identifier(t)
    86  	testVolume := testutil.Identifier(t)
    87  
    88  	defer base.Cmd("volume", "rm", "-f", testVolume).Run()
    89  	base.Cmd("volume", "create", testVolume).AssertOK()
    90  	inspectVolume := base.InspectVolume(testVolume)
    91  	namedVolumeSource := inspectVolume.Mountpoint
    92  
    93  	base.Cmd(
    94  		"run", "-d", "--name", testContainer,
    95  		"-v", "C:/mnt1",
    96  		"-v", "C:/mnt2:C:/mnt2",
    97  		"-v", "\\\\.\\pipe\\containerd-containerd:\\\\.\\pipe\\containerd-containerd",
    98  		"-v", fmt.Sprintf("%s:C:/mnt3", testVolume),
    99  		testutil.CommonImage,
   100  	).AssertOK()
   101  
   102  	inspect := base.InspectContainer(testContainer)
   103  	// convert array to map to get by key of Destination
   104  	actual := make(map[string]dockercompat.MountPoint)
   105  	for i := range inspect.Mounts {
   106  		actual[inspect.Mounts[i].Destination] = inspect.Mounts[i]
   107  	}
   108  
   109  	expected := []struct {
   110  		dest       string
   111  		mountPoint dockercompat.MountPoint
   112  	}{
   113  		// anonymous volume
   114  		{
   115  			dest: "C:\\mnt1",
   116  			mountPoint: dockercompat.MountPoint{
   117  				Type:        "volume",
   118  				Source:      "", // source of anonymous volume is a generated path, so here will not check it.
   119  				Destination: "C:\\mnt1",
   120  			},
   121  		},
   122  
   123  		// bind
   124  		{
   125  			dest: "C:\\mnt2",
   126  			mountPoint: dockercompat.MountPoint{
   127  				Type:        "bind",
   128  				Source:      "C:\\mnt2",
   129  				Destination: "C:\\mnt2",
   130  			},
   131  		},
   132  
   133  		// named pipe
   134  		{
   135  			dest: "\\\\.\\pipe\\containerd-containerd",
   136  			mountPoint: dockercompat.MountPoint{
   137  				Type:        "npipe",
   138  				Source:      "\\\\.\\pipe\\containerd-containerd",
   139  				Destination: "\\\\.\\pipe\\containerd-containerd",
   140  			},
   141  		},
   142  
   143  		// named volume
   144  		{
   145  			dest: "C:\\mnt3",
   146  			mountPoint: dockercompat.MountPoint{
   147  				Type:        "volume",
   148  				Name:        testVolume,
   149  				Source:      namedVolumeSource,
   150  				Destination: "C:\\mnt3",
   151  			},
   152  		},
   153  	}
   154  
   155  	for i := range expected {
   156  		testCase := expected[i]
   157  		t.Logf("test volume[dest=%q]", testCase.dest)
   158  
   159  		mountPoint, ok := actual[testCase.dest]
   160  		assert.Assert(base.T, ok)
   161  
   162  		assert.Equal(base.T, testCase.mountPoint.Type, mountPoint.Type)
   163  		assert.Equal(base.T, testCase.mountPoint.Destination, mountPoint.Destination)
   164  
   165  		if testCase.mountPoint.Source == "" {
   166  			// for anonymous volumes, we want to make sure that the source is not the same as the destination
   167  			assert.Assert(base.T, mountPoint.Source != testCase.mountPoint.Destination)
   168  		} else {
   169  			assert.Equal(base.T, testCase.mountPoint.Source, mountPoint.Source)
   170  		}
   171  
   172  		if testCase.mountPoint.Name != "" {
   173  			assert.Equal(base.T, testCase.mountPoint.Name, mountPoint.Name)
   174  		}
   175  	}
   176  }
   177  
   178  func TestRunMountAnonymousVolume(t *testing.T) {
   179  	t.Parallel()
   180  	base := testutil.NewBase(t)
   181  	base.Cmd("run", "--rm", "-v", "TestVolume:C:/mnt", testutil.CommonImage).AssertOK()
   182  
   183  	// For docker-campatibility, Unrecognised volume spec: invalid volume specification: 'TestVolume'
   184  	base.Cmd("run", "--rm", "-v", "TestVolume", testutil.CommonImage).AssertFail()
   185  
   186  	// Destination must be an absolute path not named volume
   187  	base.Cmd("run", "--rm", "-v", "TestVolume2:TestVolumes", testutil.CommonImage).AssertFail()
   188  }
   189  
   190  func TestRunMountRelativePath(t *testing.T) {
   191  	t.Parallel()
   192  	base := testutil.NewBase(t)
   193  	base.Cmd("run", "--rm", "-v", "./mnt:C:/mnt1", testutil.CommonImage, "cmd").AssertOK()
   194  
   195  	// Destination cannot be a relative path
   196  	base.Cmd("run", "--rm", "-v", "./mnt", testutil.CommonImage).AssertFail()
   197  	base.Cmd("run", "--rm", "-v", "./mnt:./mnt1", testutil.CommonImage, "cmd").AssertFail()
   198  }
   199  
   200  func TestRunMountNamedPipeVolume(t *testing.T) {
   201  	t.Parallel()
   202  	base := testutil.NewBase(t)
   203  	base.Cmd("run", "--rm", "-v", `\\.\pipe\containerd-containerd`, testutil.CommonImage).AssertFail()
   204  }
   205  
   206  func TestRunMountVolumeSpec(t *testing.T) {
   207  	t.Parallel()
   208  	base := testutil.NewBase(t)
   209  	base.Cmd("run", "--rm", "-v", `InvalidPathC:\TestVolume:C:\Mount`, testutil.CommonImage).AssertFail()
   210  	base.Cmd("run", "--rm", "-v", `C:\TestVolume:C:\Mount:ro,rw:boot`, testutil.CommonImage).AssertFail()
   211  
   212  	// If -v is an empty string, it will be ignored
   213  	base.Cmd("run", "--rm", "-v", "", testutil.CommonImage).AssertOK()
   214  }