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