Merge pull request #17113 from arixmkii/windows-qemu-machine-volume-mounts
Support for Windows paths in the source position of the volume mounts
This commit is contained in:
commit
77504b2582
|
|
@ -307,30 +307,10 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
|
||||||
mounts := []machine.Mount{}
|
mounts := []machine.Mount{}
|
||||||
for i, volume := range opts.Volumes {
|
for i, volume := range opts.Volumes {
|
||||||
tag := fmt.Sprintf("vol%d", i)
|
tag := fmt.Sprintf("vol%d", i)
|
||||||
paths := strings.SplitN(volume, ":", 3)
|
paths := pathsFromVolume(volume)
|
||||||
source := paths[0]
|
source := extractSourcePath(paths)
|
||||||
target := source
|
target := extractTargetPath(paths)
|
||||||
readonly := false
|
readonly, securityModel := extractMountOptions(paths)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if volumeType == VolumeTypeVirtfs {
|
if volumeType == VolumeTypeVirtfs {
|
||||||
virtfsOptions := fmt.Sprintf("local,path=%s,mount_tag=%s,security_model=%s", source, tag, securityModel)
|
virtfsOptions := fmt.Sprintf("local,path=%s,mount_tag=%s,security_model=%s", source, tag, securityModel)
|
||||||
if readonly {
|
if readonly {
|
||||||
|
|
@ -1774,3 +1754,29 @@ func isRootful() bool {
|
||||||
|
|
||||||
return !rootless.IsRootless() && os.Getuid() != -1
|
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
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package qemu
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
@ -31,3 +32,14 @@ func checkProcessStatus(processHint string, pid int, stderrBuf *bytes.Buffer) er
|
||||||
}
|
}
|
||||||
return nil
|
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]
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ package qemu
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/podman/v4/pkg/machine"
|
"github.com/containers/podman/v4/pkg/machine"
|
||||||
)
|
)
|
||||||
|
|
@ -25,3 +27,26 @@ func checkProcessStatus(processHint string, pid int, stderrBuf *bytes.Buffer) er
|
||||||
}
|
}
|
||||||
return nil
|
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, "/")
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue