mirror of
https://github.com/containers/podman.git
synced 2025-05-20 08:36:23 +08:00

Machines configured to mount local paths containing spaces failed to start on Hyper-V and silently failed to mount the folder on macOS/Linux. On Windows/hyperv, where local paths are mounted running a 9p client inside the VM, the local host path needs to be surrounding with quotation marks before using in a `podman machine ssh ...` command. A similar behavior happened on Linux/QEMU where the path was used in a SSH command to mount the folder using virtiofs. Quoting the path when buidling the command arguments fixed the problem. On macOS/libkit,applehv the path was written as is in a systemd unit name to instruct how to mount it. Escaping space chars so that they are are parsed successfully fixed this: ```diff -- enable path with spaces.mount ++ enable path\x20with\x20spaces.mount ``` Fixes https://github.com/containers/podman/issues/25500 Signed-off-by: Mario Loriedo <mario.loriedo@gmail.com>
85 lines
2.4 KiB
Go
85 lines
2.4 KiB
Go
//go:build windows
|
|
|
|
package hyperv
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/containers/podman/v5/pkg/machine"
|
|
"github.com/containers/podman/v5/pkg/machine/hyperv/vsock"
|
|
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
func removeShares(mc *vmconfigs.MachineConfig) error {
|
|
var removalErr error
|
|
|
|
for _, mount := range mc.Mounts {
|
|
if mount.VSockNumber == nil {
|
|
// nothing to do if the vsock number was never defined
|
|
continue
|
|
}
|
|
|
|
vsockReg, err := vsock.LoadHVSockRegistryEntry(*mount.VSockNumber)
|
|
if err != nil {
|
|
logrus.Debugf("Vsock %d for mountpoint %s does not have a valid registry entry, skipping removal", *mount.VSockNumber, mount.Target)
|
|
continue
|
|
}
|
|
|
|
if err := vsockReg.Remove(); err != nil {
|
|
if removalErr != nil {
|
|
logrus.Errorf("Error removing vsock: %v", removalErr)
|
|
}
|
|
removalErr = fmt.Errorf("removing vsock %d for mountpoint %s: %w", *mount.VSockNumber, mount.Target, err)
|
|
}
|
|
}
|
|
|
|
return removalErr
|
|
}
|
|
|
|
func startShares(mc *vmconfigs.MachineConfig) error {
|
|
for _, mount := range mc.Mounts {
|
|
var args []string
|
|
cleanTarget := path.Clean(mount.Target)
|
|
requiresChattr := !strings.HasPrefix(cleanTarget, "/home") && !strings.HasPrefix(cleanTarget, "/mnt")
|
|
if requiresChattr {
|
|
args = append(args, "sudo", "chattr", "-i", "/", "; ")
|
|
}
|
|
args = append(args, "sudo", "mkdir", "-p", strconv.Quote(cleanTarget), "; ")
|
|
if requiresChattr {
|
|
args = append(args, "sudo", "chattr", "+i", "/", "; ")
|
|
}
|
|
|
|
args = append(args, "sudo", "podman")
|
|
if logrus.IsLevelEnabled(logrus.DebugLevel) {
|
|
args = append(args, "--log-level=debug")
|
|
}
|
|
// just being protective here; in a perfect world, this cannot happen
|
|
if mount.VSockNumber == nil {
|
|
return errors.New("cannot start 9p shares with undefined vsock number")
|
|
}
|
|
args = append(args, "machine", "client9p", fmt.Sprintf("%d", *mount.VSockNumber), strconv.Quote(mount.Target))
|
|
|
|
if err := machine.CommonSSH(mc.SSH.RemoteUsername, mc.SSH.IdentityPath, mc.Name, mc.SSH.Port, args); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func createShares(mc *vmconfigs.MachineConfig) (err error) {
|
|
for _, mount := range mc.Mounts {
|
|
testVsock, err := vsock.NewHVSockRegistryEntry(mc.Name, vsock.Fileserver)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
mount.VSockNumber = &testVsock.Port
|
|
logrus.Debugf("Going to share directory %s via 9p on vsock %d", mount.Source, testVsock.Port)
|
|
}
|
|
return nil
|
|
}
|