mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Combine SetupWorkingDirectory for Linux and Windows
Signed-off-by: Darren Stahl <darst@microsoft.com>
This commit is contained in:
parent
3fa0d09e74
commit
6791230320
5 changed files with 65 additions and 36 deletions
|
@ -22,6 +22,7 @@ import (
|
||||||
"github.com/docker/docker/pkg/promise"
|
"github.com/docker/docker/pkg/promise"
|
||||||
"github.com/docker/docker/pkg/signal"
|
"github.com/docker/docker/pkg/signal"
|
||||||
"github.com/docker/docker/pkg/symlink"
|
"github.com/docker/docker/pkg/symlink"
|
||||||
|
"github.com/docker/docker/pkg/system"
|
||||||
"github.com/docker/docker/runconfig"
|
"github.com/docker/docker/runconfig"
|
||||||
"github.com/docker/docker/volume"
|
"github.com/docker/docker/volume"
|
||||||
containertypes "github.com/docker/engine-api/types/container"
|
containertypes "github.com/docker/engine-api/types/container"
|
||||||
|
@ -183,6 +184,30 @@ func (container *Container) WriteHostConfig() error {
|
||||||
return json.NewEncoder(f).Encode(&container.HostConfig)
|
return json.NewEncoder(f).Encode(&container.HostConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetupWorkingDirectory sets up the container's working directory as set in container.Config.WorkingDir
|
||||||
|
func (container *Container) SetupWorkingDirectory() error {
|
||||||
|
if container.Config.WorkingDir == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
container.Config.WorkingDir = filepath.Clean(container.Config.WorkingDir)
|
||||||
|
|
||||||
|
pth, err := container.GetResourcePath(container.Config.WorkingDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := system.MkdirAll(pth, 0755); err != nil {
|
||||||
|
pthInfo, err2 := os.Stat(pth)
|
||||||
|
if err2 == nil && pthInfo != nil && !pthInfo.IsDir() {
|
||||||
|
return derr.ErrorCodeNotADir.WithArgs(container.Config.WorkingDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetResourcePath evaluates `path` in the scope of the container's BaseFS, with proper path
|
// GetResourcePath evaluates `path` in the scope of the container's BaseFS, with proper path
|
||||||
// sanitisation. Symlinks are all scoped to the BaseFS of the container, as
|
// sanitisation. Symlinks are all scoped to the BaseFS of the container, as
|
||||||
// though the container's BaseFS was `/`.
|
// though the container's BaseFS was `/`.
|
||||||
|
@ -199,7 +224,8 @@ func (container *Container) WriteHostConfig() error {
|
||||||
func (container *Container) GetResourcePath(path string) (string, error) {
|
func (container *Container) GetResourcePath(path string) (string, error) {
|
||||||
// IMPORTANT - These are paths on the OS where the daemon is running, hence
|
// IMPORTANT - These are paths on the OS where the daemon is running, hence
|
||||||
// any filepath operations must be done in an OS agnostic way.
|
// any filepath operations must be done in an OS agnostic way.
|
||||||
cleanPath := filepath.Join(string(os.PathSeparator), path)
|
|
||||||
|
cleanPath := cleanResourcePath(path)
|
||||||
r, e := symlink.FollowSymlinkInScope(filepath.Join(container.BaseFS, cleanPath), container.BaseFS)
|
r, e := symlink.FollowSymlinkInScope(filepath.Join(container.BaseFS, cleanPath), container.BaseFS)
|
||||||
return r, e
|
return r, e
|
||||||
}
|
}
|
||||||
|
|
|
@ -398,34 +398,6 @@ func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network, epC
|
||||||
return createOptions, nil
|
return createOptions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetupWorkingDirectory sets up the container's working directory as set in container.Config.WorkingDir
|
|
||||||
func (container *Container) SetupWorkingDirectory() error {
|
|
||||||
if container.Config.WorkingDir == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
container.Config.WorkingDir = filepath.Clean(container.Config.WorkingDir)
|
|
||||||
|
|
||||||
pth, err := container.GetResourcePath(container.Config.WorkingDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
pthInfo, err := os.Stat(pth)
|
|
||||||
if err != nil {
|
|
||||||
if !os.IsNotExist(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := system.MkdirAll(pth, 0755); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if pthInfo != nil && !pthInfo.IsDir() {
|
|
||||||
return derr.ErrorCodeNotADir.WithArgs(container.Config.WorkingDir)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// appendNetworkMounts appends any network mounts to the array of mount points passed in
|
// appendNetworkMounts appends any network mounts to the array of mount points passed in
|
||||||
func appendNetworkMounts(container *Container, volumeMounts []volume.MountPoint) ([]volume.MountPoint, error) {
|
func appendNetworkMounts(container *Container, volumeMounts []volume.MountPoint) ([]volume.MountPoint, error) {
|
||||||
for _, mnt := range container.NetworkMounts() {
|
for _, mnt := range container.NetworkMounts() {
|
||||||
|
@ -768,3 +740,8 @@ func (container *Container) TmpfsMounts() []execdriver.Mount {
|
||||||
}
|
}
|
||||||
return mounts
|
return mounts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cleanResourcePath cleans a resource path and prepares to combine with mnt path
|
||||||
|
func cleanResourcePath(path string) string {
|
||||||
|
return filepath.Join(string(os.PathSeparator), path)
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/docker/docker/daemon/execdriver"
|
"github.com/docker/docker/daemon/execdriver"
|
||||||
"github.com/docker/docker/volume"
|
"github.com/docker/docker/volume"
|
||||||
"github.com/docker/engine-api/types/container"
|
"github.com/docker/engine-api/types/container"
|
||||||
|
@ -22,12 +25,6 @@ func (container *Container) CreateDaemonEnvironment(linkedEnv []string) []string
|
||||||
return container.Config.Env
|
return container.Config.Env
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetupWorkingDirectory initializes the container working directory.
|
|
||||||
// This is a NOOP In windows.
|
|
||||||
func (container *Container) SetupWorkingDirectory() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmountIpcMounts unmount Ipc related mounts.
|
// UnmountIpcMounts unmount Ipc related mounts.
|
||||||
// This is a NOOP on windows.
|
// This is a NOOP on windows.
|
||||||
func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
|
func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
|
||||||
|
@ -59,3 +56,15 @@ func (container *Container) UpdateContainer(hostConfig *container.HostConfig) er
|
||||||
func appendNetworkMounts(container *Container, volumeMounts []volume.MountPoint) ([]volume.MountPoint, error) {
|
func appendNetworkMounts(container *Container, volumeMounts []volume.MountPoint) ([]volume.MountPoint, error) {
|
||||||
return volumeMounts, nil
|
return volumeMounts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cleanResourcePath cleans a resource path by removing C:\ syntax, and prepares
|
||||||
|
// to combine with a volume path
|
||||||
|
func cleanResourcePath(path string) string {
|
||||||
|
if len(path) >= 2 {
|
||||||
|
c := path[0]
|
||||||
|
if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
|
||||||
|
path = path[2:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filepath.Join(string(os.PathSeparator), path)
|
||||||
|
}
|
||||||
|
|
|
@ -6568,3 +6568,20 @@ func (s *DockerSuite) TestBuildFailsGitNotCallable(c *check.C) {
|
||||||
c.Assert(err, checker.NotNil)
|
c.Assert(err, checker.NotNil)
|
||||||
c.Assert(out, checker.Contains, "unable to prepare context: unable to find 'git': ")
|
c.Assert(out, checker.Contains, "unable to prepare context: unable to find 'git': ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestBuildWorkdirWindowsPath tests that a Windows style path works as a workdir
|
||||||
|
func (s *DockerSuite) TestBuildWorkdirWindowsPath(c *check.C) {
|
||||||
|
testRequires(c, DaemonIsWindows)
|
||||||
|
name := "testbuildworkdirwindowspath"
|
||||||
|
|
||||||
|
_, err := buildImage(name, `
|
||||||
|
FROM windowsservercore
|
||||||
|
RUN mkdir C:\\work
|
||||||
|
WORKDIR C:\\work
|
||||||
|
RUN if "%CD%" NEQ "C:\work" exit -1
|
||||||
|
`, true)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1723,7 +1723,7 @@ func (s *DockerSuite) TestRunWorkdirExistsAndIsFile(c *check.C) {
|
||||||
expected := "Cannot mkdir: /bin/cat is not a directory"
|
expected := "Cannot mkdir: /bin/cat is not a directory"
|
||||||
if daemonPlatform == "windows" {
|
if daemonPlatform == "windows" {
|
||||||
existingFile = `\windows\system32\ntdll.dll`
|
existingFile = `\windows\system32\ntdll.dll`
|
||||||
expected = "The directory name is invalid"
|
expected = `Cannot mkdir: \windows\system32\ntdll.dll is not a directory.`
|
||||||
}
|
}
|
||||||
|
|
||||||
out, exitCode, err := dockerCmdWithError("run", "-w", existingFile, "busybox")
|
out, exitCode, err := dockerCmdWithError("run", "-w", existingFile, "busybox")
|
||||||
|
|
Loading…
Reference in a new issue