mirror of
https://github.com/containers/podman.git
synced 2025-06-27 13:38:49 +08:00
Support for Windows paths in the source position of the volume mounts
There are 2 things added. First there is added support for handling drive letters while doing value split. If drive letter is detected, then max number of elements will be increased by one, but then first two will be concatenated to reconstruct the path. Second part is basic, but working, conversion of Windows path to Unix path to be used, when target path is not explicitly specified. Signed-off-by: Arthur Sengileyev <arthur.sengileyev@gmail.com>
This commit is contained in:
@ -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
|
||||
}
|
||||
|
@ -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]
|
||||
}
|
||||
|
@ -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, "/")
|
||||
}
|
||||
|
Reference in New Issue
Block a user