mirror of
https://github.com/containers/podman.git
synced 2025-11-29 01:28:22 +08:00
Previously, each new HyperV Podman machine required creating new hvsock registry entries, necessitating administrator privileges. This change modifies the HyperV provider to reuse existing hvsock entries if found. This is possible due to Podman's current limitation of running only one HyperV machine at a time. As a result, administrator privileges are only needed for the first initial machine setup (when the registry is empty). Subsequent machines can be created by users in the "Hyper-V Administrators" group without being Admin. Hvsock entries are no longer deleted on each machine removal; cleanup is handled when the last machine gets removed. Signed-off-by: lstocchi <lstocchi@redhat.com>
80 lines
2.5 KiB
Go
80 lines
2.5 KiB
Go
//go:build windows
|
|
|
|
package hyperv
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/containers/podman/v6/pkg/machine"
|
|
"github.com/containers/podman/v6/pkg/machine/hyperv/vsock"
|
|
"github.com/containers/podman/v6/pkg/machine/vmconfigs"
|
|
"github.com/containers/podman/v6/pkg/machine/windows"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
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.LocalhostSSH(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) {
|
|
fileServerVsocks, err := vsock.LoadAllHVSockRegistryEntriesByPurpose(vsock.Fileserver)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to load existing file server vsock registry entries: %w", err)
|
|
}
|
|
for i, mount := range mc.Mounts {
|
|
var testVsock *vsock.HVSockRegistryEntry
|
|
|
|
// Check if there's an existing file server vsock entry that can be reused for the current mount.
|
|
if i < len(fileServerVsocks) {
|
|
testVsock = fileServerVsocks[i]
|
|
} else {
|
|
// If no existing vsock entry can be reused, a new one must be created.
|
|
// Creating a new HVSockRegistryEntry requires administrator privileges.
|
|
if !windows.HasAdminRights() {
|
|
if i == 0 {
|
|
return ErrHypervRegistryInitRequiresElevation
|
|
}
|
|
return ErrHypervRegistryUpdateRequiresElevation
|
|
}
|
|
testVsock, err = vsock.NewHVSockRegistryEntry(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
|
|
}
|