summaryrefslogtreecommitdiff
path: root/pkg/specgen/winpath.go
diff options
context:
space:
mode:
authorJason T. Greene <jason.greene@redhat.com>2022-03-24 22:07:55 -0500
committerJason T. Greene <jason.greene@redhat.com>2022-04-25 13:52:27 -0500
commitb0d36f63513ee64fa1c1eff4d1045a7633804f12 (patch)
tree3bb66bef188e12daae252a18234e544a9be1b145 /pkg/specgen/winpath.go
parent3b6ffcd290978f5e0110e925c212d6396accee10 (diff)
downloadpodman-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.go59
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
+}