Create destination mount dir if it doesn't exist

PiperOrigin-RevId: 199175296
Change-Id: I694ad1cfa65572c92f77f22421fdcac818f44630
This commit is contained in:
Fabricio Voznika
2018-06-04 12:31:35 -07:00
committed by Shentubot
parent 78ccd1298e
commit 6c585b8eb6
2 changed files with 65 additions and 19 deletions
+11 -1
View File
@@ -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)
+54 -18
View File
@@ -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)
// 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)
}
ws, err := s.Wait()
if err != nil {
t.Errorf("error waiting on container: %v", 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)
}
}