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