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