github.com/vieux/docker@v0.6.3-0.20161004191708-e097c2a938c7/container/archive.go (about) 1 package container 2 3 import ( 4 "os" 5 "path/filepath" 6 7 "github.com/docker/docker/api/types" 8 "github.com/docker/docker/pkg/archive" 9 "github.com/docker/docker/pkg/system" 10 ) 11 12 // ResolvePath resolves the given path in the container to a resource on the 13 // host. Returns a resolved path (absolute path to the resource on the host), 14 // the absolute path to the resource relative to the container's rootfs, and 15 // an error if the path points to outside the container's rootfs. 16 func (container *Container) ResolvePath(path string) (resolvedPath, absPath string, err error) { 17 // Check if a drive letter supplied, it must be the system drive. No-op except on Windows 18 path, err = system.CheckSystemDriveAndRemoveDriveLetter(path) 19 if err != nil { 20 return "", "", err 21 } 22 23 // Consider the given path as an absolute path in the container. 24 absPath = archive.PreserveTrailingDotOrSeparator(filepath.Join(string(filepath.Separator), path), path) 25 26 // Split the absPath into its Directory and Base components. We will 27 // resolve the dir in the scope of the container then append the base. 28 dirPath, basePath := filepath.Split(absPath) 29 30 resolvedDirPath, err := container.GetResourcePath(dirPath) 31 if err != nil { 32 return "", "", err 33 } 34 35 // resolvedDirPath will have been cleaned (no trailing path separators) so 36 // we can manually join it with the base path element. 37 resolvedPath = resolvedDirPath + string(filepath.Separator) + basePath 38 39 return resolvedPath, absPath, nil 40 } 41 42 // StatPath is the unexported version of StatPath. Locks and mounts should 43 // be acquired before calling this method and the given path should be fully 44 // resolved to a path on the host corresponding to the given absolute path 45 // inside the container. 46 func (container *Container) StatPath(resolvedPath, absPath string) (stat *types.ContainerPathStat, err error) { 47 lstat, err := os.Lstat(resolvedPath) 48 if err != nil { 49 return nil, err 50 } 51 52 var linkTarget string 53 if lstat.Mode()&os.ModeSymlink != 0 { 54 // Fully evaluate the symlink in the scope of the container rootfs. 55 hostPath, err := container.GetResourcePath(absPath) 56 if err != nil { 57 return nil, err 58 } 59 60 linkTarget, err = filepath.Rel(container.BaseFS, hostPath) 61 if err != nil { 62 return nil, err 63 } 64 65 // Make it an absolute path. 66 linkTarget = filepath.Join(string(filepath.Separator), linkTarget) 67 } 68 69 return &types.ContainerPathStat{ 70 Name: filepath.Base(absPath), 71 Size: lstat.Size(), 72 Mode: lstat.Mode(), 73 Mtime: lstat.ModTime(), 74 LinkTarget: linkTarget, 75 }, nil 76 }