diff options
author | Jason T. Greene <jason.greene@redhat.com> | 2022-03-24 22:07:55 -0500 |
---|---|---|
committer | Jason T. Greene <jason.greene@redhat.com> | 2022-04-25 13:52:27 -0500 |
commit | b0d36f63513ee64fa1c1eff4d1045a7633804f12 (patch) | |
tree | 3bb66bef188e12daae252a18234e544a9be1b145 /pkg/specgen/winpath.go | |
parent | 3b6ffcd290978f5e0110e925c212d6396accee10 (diff) | |
download | podman-b0d36f63513ee64fa1c1eff4d1045a7633804f12.tar.gz podman-b0d36f63513ee64fa1c1eff4d1045a7633804f12.tar.bz2 podman-b0d36f63513ee64fa1c1eff4d1045a7633804f12.zip |
Implements Windows volume/mount support
Based on WSL2 9p support: remaps windows paths to /mnt/<drive> locations for
both podman and Docker API clients.
Signed-off-by: Jason T. Greene <jason.greene@redhat.com>
Diffstat (limited to 'pkg/specgen/winpath.go')
-rw-r--r-- | pkg/specgen/winpath.go | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/pkg/specgen/winpath.go b/pkg/specgen/winpath.go new file mode 100644 index 000000000..f4249fab1 --- /dev/null +++ b/pkg/specgen/winpath.go @@ -0,0 +1,59 @@ +package specgen + +import ( + "fmt" + "strings" + "unicode" + + "github.com/pkg/errors" +) + +func isHostWinPath(path string) bool { + return shouldResolveWinPaths() && strings.HasPrefix(path, `\\`) || hasWinDriveScheme(path, 0) || winPathExists(path) +} + +func hasWinDriveScheme(path string, start int) bool { + if len(path) < start+2 || path[start+1] != ':' { + return false + } + + drive := rune(path[start]) + return drive < unicode.MaxASCII && unicode.IsLetter(drive) +} + +// Converts a Windows path to a WSL guest path if local env is a WSL linux guest or this is a Windows client. +func ConvertWinMountPath(path string) (string, error) { + if !shouldResolveWinPaths() { + return path, nil + } + + if strings.HasPrefix(path, "/") { + // Handle /[driveletter]/windows/path form (e.g. c:\Users\bar == /c/Users/bar) + if len(path) > 2 && path[2] == '/' && shouldResolveUnixWinVariant(path) { + drive := unicode.ToLower(rune(path[1])) + if unicode.IsLetter(drive) && drive <= unicode.MaxASCII { + return fmt.Sprintf("/mnt/%c/%s", drive, path[3:]), nil + } + } + + // unix path - pass through + return path, nil + } + + // Convert remote win client relative paths to absolute + path = resolveRelativeOnWindows(path) + + // Strip extended marker prefix if present + path = strings.TrimPrefix(path, `\\?\`) + + // Drive installed via wsl --mount + if strings.HasPrefix(path, `\\.\`) { + path = "/mnt/wsl/" + path[4:] + } else if len(path) > 1 && path[1] == ':' { + path = "/mnt/" + strings.ToLower(path[0:1]) + path[2:] + } else { + return path, errors.New("unsupported UNC path") + } + + return strings.ReplaceAll(path, `\`, "/"), nil +} |