diff options
-rw-r--r-- | runsc/boot/fs.go | 2 | ||||
-rw-r--r-- | runsc/container/container_test.go | 71 |
2 files changed, 72 insertions, 1 deletions
diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go index f36bcdc2e..51c8d620d 100644 --- a/runsc/boot/fs.go +++ b/runsc/boot/fs.go @@ -207,7 +207,7 @@ func createRootMount(ctx context.Context, spec *specs.Spec, conf *Config, fds *f return nil, fmt.Errorf("error adding submount overlay: %v", err) } - if conf.Overlay { + if conf.Overlay && !spec.Root.Readonly { log.Debugf("Adding overlay on top of root mount") // Overlay a tmpfs filesystem on top of the root. rootInode, err = addOverlay(ctx, conf, rootInode, "root-overlay-upper", mf) diff --git a/runsc/container/container_test.go b/runsc/container/container_test.go index d2f3cc14a..72b115628 100644 --- a/runsc/container/container_test.go +++ b/runsc/container/container_test.go @@ -998,6 +998,77 @@ func TestMountNewDir(t *testing.T) { } } +func TestReadonlyRoot(t *testing.T) { + spec := testutil.NewSpecWithArgs("/bin/touch", "/foo") + spec.Root.Readonly = true + rootDir, bundleDir, conf, err := testutil.SetupContainer(spec) + if err != nil { + t.Fatalf("error setting up container: %v", err) + } + defer os.RemoveAll(rootDir) + defer os.RemoveAll(bundleDir) + + conf.Overlay = true + + // 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) + } + 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.Fatalf("error waiting on container: %v", err) + } + if !ws.Exited() || syscall.Errno(ws.ExitStatus()) != syscall.EPERM { + t.Fatalf("container failed, waitStatus: %v", ws) + } +} + +func TestReadonlyMount(t *testing.T) { + spec := testutil.NewSpecWithArgs("/bin/touch", "/foo/file") + dir, err := ioutil.TempDir("", "ro-mount") + if err != nil { + t.Fatalf("ioutil.TempDir() failed: %v", err) + } + spec.Mounts = append(spec.Mounts, specs.Mount{ + Destination: "/foo", + Source: dir, + Type: "bind", + Options: []string{"ro"}, + }) + spec.Root.Readonly = false + + rootDir, bundleDir, conf, err := testutil.SetupContainer(spec) + if err != nil { + t.Fatalf("error setting up container: %v", err) + } + defer os.RemoveAll(rootDir) + defer os.RemoveAll(bundleDir) + + conf.Overlay = true + + // 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) + } + 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.Fatalf("error waiting on container: %v", err) + } + if !ws.Exited() || syscall.Errno(ws.ExitStatus()) != syscall.EPERM { + t.Fatalf("container failed, waitStatus: %v", ws) + } +} + // TestAbbreviatedIDs checks that runsc supports using abbreviated container // IDs in place of full IDs. func TestAbbreviatedIDs(t *testing.T) { |