diff --git a/cmd/limactl/shell.go b/cmd/limactl/shell.go index 36454010965..dbe8a7543f5 100644 --- a/cmd/limactl/shell.go +++ b/cmd/limactl/shell.go @@ -8,7 +8,6 @@ import ( "fmt" "os" "os/exec" - "path" "runtime" "strconv" "strings" @@ -17,6 +16,7 @@ import ( "github.com/coreos/go-semver/semver" "github.com/lima-vm/lima/pkg/instance" "github.com/lima-vm/lima/pkg/ioutilx" + "github.com/lima-vm/lima/pkg/limayaml" networks "github.com/lima-vm/lima/pkg/networks/reconcile" "github.com/lima-vm/lima/pkg/sshutil" "github.com/lima-vm/lima/pkg/store" @@ -139,10 +139,10 @@ func shellAction(cmd *cobra.Command, args []string) error { if workDir != "" { changeDirCmd = fmt.Sprintf("cd %s || exit 1", shellescape.Quote(workDir)) // FIXME: check whether y.Mounts contains the home, not just len > 0 - } else if len(inst.Config.Mounts) > 0 { + } else if len(inst.Config.Mounts) > 0 || inst.VMType == limayaml.WSL2 { hostCurrentDir, err := os.Getwd() if err == nil && runtime.GOOS == "windows" { - hostCurrentDir, err = mountDirFromWindowsDir(hostCurrentDir) + hostCurrentDir, err = mountDirFromWindowsDir(inst, hostCurrentDir) } if err == nil { changeDirCmd = fmt.Sprintf("cd %s", shellescape.Quote(hostCurrentDir)) @@ -152,7 +152,7 @@ func shellAction(cmd *cobra.Command, args []string) error { } hostHomeDir, err := os.UserHomeDir() if err == nil && runtime.GOOS == "windows" { - hostHomeDir, err = mountDirFromWindowsDir(hostHomeDir) + hostHomeDir, err = mountDirFromWindowsDir(inst, hostHomeDir) } if err == nil { changeDirCmd = fmt.Sprintf("%s || cd %s", changeDirCmd, shellescape.Quote(hostHomeDir)) @@ -244,12 +244,12 @@ func shellAction(cmd *cobra.Command, args []string) error { return sshCmd.Run() } -func mountDirFromWindowsDir(dir string) (string, error) { - dir, err := ioutilx.WindowsSubsystemPath(dir) - if err == nil && !strings.HasPrefix(dir, "/mnt/") { - dir = path.Join("/mnt", dir) +func mountDirFromWindowsDir(inst *store.Instance, dir string) (string, error) { + if inst.VMType == limayaml.WSL2 { + distroName := "lima-" + inst.Name + return ioutilx.WindowsSubsystemPathForLinux(dir, distroName) } - return dir, err + return ioutilx.WindowsSubsystemPath(dir) } func shellBashComplete(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { diff --git a/pkg/ioutilx/ioutilx.go b/pkg/ioutilx/ioutilx.go index cd91e40c77f..9b5ccbe019a 100644 --- a/pkg/ioutilx/ioutilx.go +++ b/pkg/ioutilx/ioutilx.go @@ -53,7 +53,16 @@ func WindowsSubsystemPath(orig string) (string, error) { out, err := exec.Command("cygpath", filepath.ToSlash(orig)).CombinedOutput() if err != nil { logrus.WithError(err).Errorf("failed to convert path to mingw, maybe not using Git ssh?") - return orig, err + return "", err + } + return strings.TrimSpace(string(out)), nil +} + +func WindowsSubsystemPathForLinux(orig, distro string) (string, error) { + out, err := exec.Command("wsl", "-d", distro, "--exec", "wslpath", filepath.ToSlash(orig)).CombinedOutput() + if err != nil { + logrus.WithError(err).Errorf("failed to convert path to mingw, maybe wsl command is not operational?") + return "", err } return strings.TrimSpace(string(out)), nil } diff --git a/pkg/osutil/user.go b/pkg/osutil/user.go index b34f5c3d59f..8a47ffee58d 100644 --- a/pkg/osutil/user.go +++ b/pkg/osutil/user.go @@ -7,6 +7,7 @@ import ( "fmt" "os/exec" "os/user" + "path" "path/filepath" "regexp" "runtime" @@ -149,7 +150,19 @@ func LimaUser(limaVersion string, warn bool) *user.User { if err != nil { logrus.Debug(err) } else { - home += ".linux" + // Trim mount prefix within Subsystem + // cygwin/msys2 cygpath could have prefix for drive mounts configured via /etc/fstab + // wsl wslpath could have prefix for drive mounts configured via [automount] section in wsl.conf + drivePath, err := ioutilx.WindowsSubsystemPath(filepath.VolumeName(limaUser.HomeDir) + "/") + if err != nil { + logrus.Debug(err) + } else { + prefix := path.Dir(strings.TrimSuffix(drivePath, "/")) + if prefix != "/" { + home = strings.TrimPrefix(home, prefix) + } + home += ".linux" + } } if home == "" { drive := filepath.VolumeName(limaUser.HomeDir) @@ -160,10 +173,6 @@ func LimaUser(limaVersion string, warn bool) *user.User { home += ".linux" } if !regexPath.MatchString(limaUser.HomeDir) { - // Trim prefix of well known default mounts - if strings.HasPrefix(home, "/mnt/") { - home = strings.TrimPrefix(home, "/mnt") - } warning := fmt.Sprintf("local home %q is not a valid Linux path (must match %q); using %q home instead", limaUser.HomeDir, regexPath.String(), home) warnings = append(warnings, warning)