diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index 4f25b4d26c..0ec1bd1958 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -301,30 +301,10 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) { mounts := []machine.Mount{} for i, volume := range opts.Volumes { tag := fmt.Sprintf("vol%d", i) - paths := strings.SplitN(volume, ":", 3) - source := paths[0] - target := source - readonly := false - securityModel := "none" - if len(paths) > 1 { - target = paths[1] - } - if len(paths) > 2 { - options := paths[2] - volopts := strings.Split(options, ",") - for _, o := range volopts { - switch { - case o == "rw": - readonly = false - case o == "ro": - readonly = true - case strings.HasPrefix(o, "security_model="): - securityModel = strings.Split(o, "=")[1] - default: - fmt.Printf("Unknown option: %s\n", o) - } - } - } + paths := pathsFromVolume(volume) + source := extractSourcePath(paths) + target := extractTargetPath(paths) + readonly, securityModel := extractMountOptions(paths) if volumeType == VolumeTypeVirtfs { virtfsOptions := fmt.Sprintf("local,path=%s,mount_tag=%s,security_model=%s", source, tag, securityModel) if readonly { @@ -1756,3 +1736,29 @@ func isRootful() bool { return !rootless.IsRootless() && os.Getuid() != -1 } + +func extractSourcePath(paths []string) string { + return paths[0] +} + +func extractMountOptions(paths []string) (bool, string) { + readonly := false + securityModel := "none" + if len(paths) > 2 { + options := paths[2] + volopts := strings.Split(options, ",") + for _, o := range volopts { + switch { + case o == "rw": + readonly = false + case o == "ro": + readonly = true + case strings.HasPrefix(o, "security_model="): + securityModel = strings.Split(o, "=")[1] + default: + fmt.Printf("Unknown option: %s\n", o) + } + } + } + return readonly, securityModel +} diff --git a/pkg/machine/qemu/machine_unix.go b/pkg/machine/qemu/machine_unix.go index 84ee191d18..b798d03dba 100644 --- a/pkg/machine/qemu/machine_unix.go +++ b/pkg/machine/qemu/machine_unix.go @@ -6,6 +6,7 @@ package qemu import ( "bytes" "fmt" + "strings" "syscall" "golang.org/x/sys/unix" @@ -31,3 +32,14 @@ func checkProcessStatus(processHint string, pid int, stderrBuf *bytes.Buffer) er } return nil } + +func pathsFromVolume(volume string) []string { + return strings.SplitN(volume, ":", 3) +} + +func extractTargetPath(paths []string) string { + if len(paths) > 1 { + return paths[1] + } + return paths[0] +} diff --git a/pkg/machine/qemu/machine_windows.go b/pkg/machine/qemu/machine_windows.go index 6c63faf50c..04065cb1d3 100644 --- a/pkg/machine/qemu/machine_windows.go +++ b/pkg/machine/qemu/machine_windows.go @@ -3,6 +3,8 @@ package qemu import ( "bytes" "fmt" + "regexp" + "strings" "github.com/containers/podman/v4/pkg/machine" ) @@ -25,3 +27,26 @@ func checkProcessStatus(processHint string, pid int, stderrBuf *bytes.Buffer) er } return nil } + +func pathsFromVolume(volume string) []string { + paths := strings.SplitN(volume, ":", 3) + driveLetterMatcher := regexp.MustCompile(`^(?:\\\\[.?]\\)?[a-zA-Z]$`) + if len(paths) > 1 && driveLetterMatcher.MatchString(paths[0]) { + paths = strings.SplitN(volume, ":", 4) + paths = append([]string{paths[0] + ":" + paths[1]}, paths[2:]...) + } + return paths +} + +func extractTargetPath(paths []string) string { + if len(paths) > 1 { + return paths[1] + } + target := strings.ReplaceAll(paths[0], "\\", "/") + target = strings.ReplaceAll(target, ":", "/") + if strings.HasPrefix(target, "//./") || strings.HasPrefix(target, "//?/") { + target = target[4:] + } + dedup := regexp.MustCompile(`//+`) + return dedup.ReplaceAllLiteralString("/"+target, "/") +}