Skip to content

Commit

Permalink
bugfix: fix failed to run a container with specifing a non-exist work…
Browse files Browse the repository at this point in the history
…ing directory

Signed-off-by: Michael Wan <[email protected]>
  • Loading branch information
HusterWan committed Aug 21, 2018
1 parent c4fd9bb commit 514c2cf
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 0 deletions.
28 changes: 28 additions & 0 deletions daemon/mgr/container_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,12 @@ func (mgr *ContainerManager) initContainerStorage(ctx context.Context, c *Contai
}
}()

// try to setup container working directory
if err := mgr.SetupWorkingDirectory(ctx, c); err != nil {
// TODO(ziren): now we just log the error info when failed to setup workingdirectory
logrus.Errorf("failed to setup container %s working directory: %v", c.ID, err)
}

// parse volume config
if err = mgr.generateMountPoints(ctx, c); err != nil {
return errors.Wrap(err, "failed to parse volume argument")
Expand All @@ -682,6 +688,28 @@ func (mgr *ContainerManager) initContainerStorage(ctx context.Context, c *Contai
return nil
}

// SetupWorkingDirectory setup working directory for container
func (mgr *ContainerManager) SetupWorkingDirectory(ctx context.Context, c *Container) error {
if c.Config.WorkingDir == "" {
return nil
}

if c.MountFS == "" {
mgr.setMountFS(ctx, c)
}

c.Config.WorkingDir = filepath.Clean(c.Config.WorkingDir)

path := filepath.Join(c.MountFS, c.Config.WorkingDir)
// TODO(ziren): not care about File mode
err := os.MkdirAll(path, 0755)
if err != nil && !os.IsExist(err) {
return err
}

return nil
}

func copyImageContent(source, destination string) error {
fi, err := os.Stat(source)
if err != nil {
Expand Down
110 changes: 110 additions & 0 deletions test/cli_run_working_dir_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package main

import (
"encoding/json"
"strings"

"github.com/alibaba/pouch/apis/types"
"github.com/alibaba/pouch/test/command"
"github.com/alibaba/pouch/test/environment"

"github.com/go-check/check"
"github.com/gotestyourself/gotestyourself/icmd"
)

// PouchRunWorkingDirSuite is the test suite for run CLI.
type PouchRunWorkingDirSuite struct{}

func init() {
check.Suite(&PouchRunWorkingDirSuite{})
}

// SetUpSuite does common setup in the beginning of each test suite.
func (suite *PouchRunWorkingDirSuite) SetUpSuite(c *check.C) {
SkipIfFalse(c, environment.IsLinux)

environment.PruneAllContainers(apiClient)

PullImage(c, busyboxImage)
}

// TearDownTest does cleanup work in the end of each test.
func (suite *PouchRunWorkingDirSuite) TearDownTest(c *check.C) {
}

// TestRunWithExistWorkingDir is to verify the valid running container
// with specifying working dir
func (suite *PouchRunWorkingDirSuite) TestRunWithExistWorkingDir(c *check.C) {
SkipIfFalse(c, environment.IsMemorySupport)

cname := "TestRunWithExistWorkingDir"
res := command.PouchRun("run", "-d", "-m", "100m", "-w", "/root", "--name", cname, busyboxImage, "top")
defer DelContainerForceMultyTime(c, cname)
res.Assert(c, icmd.Success)

// test if the value is in inspect result
res = command.PouchRun("inspect", cname)
res.Assert(c, icmd.Success)

result := []types.ContainerJSON{}
if err := json.Unmarshal([]byte(res.Stdout()), &result); err != nil {
c.Errorf("failed to decode inspect output: %v", err)
}
c.Assert(result[0].Config.WorkingDir, check.Equals, "/root")
}

// TestRunWithNotExistWorkingDir is to verify the valid running container
// with specifying a not exist working dir
func (suite *PouchRunWorkingDirSuite) TestRunWithNotExistWorkingDir(c *check.C) {
SkipIfFalse(c, environment.IsMemorySupport)

cname := "TestRunWithNotExistWorkingDir"
res := command.PouchRun("run", "-d", "-m", "100m", "-w", "/tmp/notexist/dir", "--name", cname, busyboxImage, "top")
defer DelContainerForceMultyTime(c, cname)
res.Assert(c, icmd.Success)

// test if the value is in inspect result
res = command.PouchRun("inspect", cname)
res.Assert(c, icmd.Success)

result := []types.ContainerJSON{}
if err := json.Unmarshal([]byte(res.Stdout()), &result); err != nil {
c.Errorf("failed to decode inspect output: %v", err)
}
c.Assert(result[0].Config.WorkingDir, check.Equals, "/tmp/notexist/dir")
}

// TestRunWithWorkingDir is to verify the valid running container
// with specifying working dir
func (suite *PouchRunWorkingDirSuite) TestRunWithWorkingDir(c *check.C) {
SkipIfFalse(c, environment.IsMemorySupport)
dir := "/tmp/testworkingdir"

cname := "TestRunWithNotExistWorkingDir"
res := command.PouchRun("run", "-m", "100m", "-w", dir, "--name", cname, busyboxImage, "pwd")
defer DelContainerForceMultyTime(c, cname)
res.Assert(c, icmd.Success)

out := res.Combined()
out = strings.TrimSpace(out)
if out != dir {
c.Errorf("failed to set working directory, expect %s, got %s", dir, out)
}
}

// TestRunWithWorkingDirExistAndIsFile is to verify the valid running container
// with specifying a exist file as working directory
func (suite *PouchRunWorkingDirSuite) TestRunWithWorkingDirExistAndIsFile(c *check.C) {
SkipIfFalse(c, environment.IsMemorySupport)
dir := "/bin/cat"

cname := "TestRunWithWorkingDirExistAndIsFile"
res := command.PouchRun("run", "-m", "100m", "-w", dir, "--name", cname, busyboxImage, "pwd")
defer DelContainerForceMultyTime(c, cname)
c.Assert(res.Stderr(), check.NotNil)

expected := "not a directory"
if out := res.Combined(); !strings.Contains(out, expected) {
c.Errorf("error information unmatched, expect %s, got %s", expected, out)
}
}

0 comments on commit 514c2cf

Please sign in to comment.