summaryrefslogtreecommitdiffhomepage
path: root/runsc
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2018-06-04 12:30:47 -0700
committerShentubot <shentubot@google.com>2018-06-04 12:31:35 -0700
commit6c585b8eb69362db9af5ed150763096874832b86 (patch)
tree12f2269ec85c4e58d121377686377fd09a9d4e7e /runsc
parent78ccd1298e1386d9c5e0eb10d328ecb16b28ea02 (diff)
Create destination mount dir if it doesn't exist
PiperOrigin-RevId: 199175296 Change-Id: I694ad1cfa65572c92f77f22421fdcac818f44630
Diffstat (limited to 'runsc')
-rw-r--r--runsc/boot/fs.go12
-rw-r--r--runsc/container/container_test.go72
2 files changed, 65 insertions, 19 deletions
diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go
index e5b7663d0..82bbea4d7 100644
--- a/runsc/boot/fs.go
+++ b/runsc/boot/fs.go
@@ -288,11 +288,21 @@ func mountSubmount(ctx context.Context, spec *specs.Spec, conf *Config, mns *fs.
if useOverlay {
log.Debugf("Adding overlay on top of mount %q", m.Destination)
- if inode, err = addOverlay(ctx, conf, inode, m.Type, mf); err != nil {
+ inode, err = addOverlay(ctx, conf, inode, m.Type, mf)
+ if err != nil {
return err
}
}
+ // Create destination in case it doesn't exist. This is required, in addition
+ // to 'addSubmountOverlay', in case there are symlinks to create directories
+ // in the right location, e.g.
+ // mount: /var/run/secrets, may be created in '/run/secrets' if
+ // '/var/run' => '/var'.
+ if err := mkdirAll(ctx, mns, m.Destination); err != nil {
+ return err
+ }
+
root := mns.Root()
defer root.DecRef()
dirent, err := mns.FindInode(ctx, root, nil, m.Destination, linux.MaxSymlinkTraversals)
diff --git a/runsc/container/container_test.go b/runsc/container/container_test.go
index 3af8d620c..da59c0331 100644
--- a/runsc/container/container_test.go
+++ b/runsc/container/container_test.go
@@ -92,6 +92,35 @@ func procListToString(pl []*control.Process) string {
return fmt.Sprintf("[%s]", strings.Join(strs, ","))
}
+// run starts the sandbox and waits for it to exit, checking that the
+// application succeeded.
+func run(spec *specs.Spec) error {
+ rootDir, bundleDir, conf, err := testutil.SetupContainer(spec)
+ if err != nil {
+ return fmt.Errorf("error setting up container: %v", err)
+ }
+ defer os.RemoveAll(rootDir)
+ defer os.RemoveAll(bundleDir)
+
+ // Create, start and wait for the container.
+ s, err := container.Create(testutil.UniqueContainerID(), spec, conf, bundleDir, "", "")
+ if err != nil {
+ return fmt.Errorf("error creating container: %v", err)
+ }
+ defer s.Destroy()
+ if err := s.Start(conf); err != nil {
+ return fmt.Errorf("error starting container: %v", err)
+ }
+ ws, err := s.Wait()
+ if err != nil {
+ return fmt.Errorf("error waiting on container: %v", err)
+ }
+ if !ws.Exited() || ws.ExitStatus() != 0 {
+ return fmt.Errorf("container failed, waitStatus: %v", ws)
+ }
+ return nil
+}
+
// TestLifecycle tests the basic Create/Start/Signal/Destroy container lifecycle.
// It verifies after each step that the container can be loaded from disk, and
// has the correct status.
@@ -600,27 +629,34 @@ func TestRunNonRoot(t *testing.T) {
Type: "bind",
})
- rootDir, bundleDir, conf, err := testutil.SetupContainer(spec)
- if err != nil {
- t.Fatalf("error setting up container: %v", err)
+ if err := run(spec); err != nil {
+ t.Fatalf("error running sadbox: %v", err)
}
- defer os.RemoveAll(rootDir)
- defer os.RemoveAll(bundleDir)
+}
- // Create, start and wait for the container.
- s, err := container.Create(testutil.UniqueContainerID(), spec, conf, bundleDir, "", "")
- if err != nil {
- t.Fatalf("error creating container: %v", err)
+// TestMountNewDir check that runsc will create destination directory if it
+// doesn't exit.
+func TestMountNewDir(t *testing.T) {
+ srcDir := path.Join(os.TempDir(), "src", "newdir", "anotherdir")
+ if err := os.MkdirAll(srcDir, 0755); err != nil {
+ t.Fatalf("os.MkDir(%q) failed: %v", srcDir, err)
}
- defer s.Destroy()
- if err := s.Start(conf); err != nil {
- t.Fatalf("error starting container: %v", err)
- }
- ws, err := s.Wait()
- if err != nil {
- t.Errorf("error waiting on container: %v", err)
+
+ // Attempt to remove dir to ensure it doesn't exist.
+ mountDir := path.Join(os.TempDir(), "newdir")
+ if err := os.RemoveAll(mountDir); err != nil {
+ t.Fatalf("os.RemoveAll(%q) failed: %v", mountDir, err)
}
- if !ws.Exited() || ws.ExitStatus() != 0 {
- t.Errorf("container failed, waitStatus: %v", ws)
+ mountDir = path.Join(mountDir, "anotherdir")
+
+ spec := testutil.NewSpecWithArgs("/bin/ls", mountDir)
+ spec.Mounts = append(spec.Mounts, specs.Mount{
+ Destination: mountDir,
+ Source: srcDir,
+ Type: "bind",
+ })
+
+ if err := run(spec); err != nil {
+ t.Fatalf("error running sadbox: %v", err)
}
}