Skip to content

Commit

Permalink
Support for Windows paths in the source position of the volume mounts
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
arixmkii committed Jan 30, 2023
1 parent b7987ca commit 952049f
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 24 deletions.
54 changes: 30 additions & 24 deletions pkg/machine/qemu/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
}
12 changes: 12 additions & 0 deletions pkg/machine/qemu/machine_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package qemu
import (
"bytes"
"fmt"
"strings"
"syscall"

"golang.org/x/sys/unix"
Expand All @@ -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]
}
25 changes: 25 additions & 0 deletions pkg/machine/qemu/machine_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package qemu
import (
"bytes"
"fmt"
"regexp"
"strings"

"github.com/containers/podman/v4/pkg/machine"
)
Expand All @@ -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, "/")
}

0 comments on commit 952049f

Please sign in to comment.