Merge pull request #18258 from baude/hypervsockets

hyperv: add podman socket mapping
This commit is contained in:
openshift-ci[bot] 2023-04-20 17:14:45 +00:00 committed by GitHub
commit c325cfd462
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 82 additions and 51 deletions

View File

@ -400,3 +400,13 @@ func (v VMType) String() string {
} }
return "qemu" return "qemu"
} }
type APIForwardingState int
const (
NoForwarding APIForwardingState = iota
ClaimUnsupported
NotInstalled
MachineLocal
DockerGlobal
)

View File

@ -42,21 +42,11 @@ const (
// working code. // working code.
VolumeTypeVirtfs = "virtfs" VolumeTypeVirtfs = "virtfs"
MountType9p = "9p" MountType9p = "9p"
dockerSock = "/var/run/docker.sock" dockerSockPath = "/var/run/docker.sock"
dockerConnectTimeout = 5 * time.Second dockerConnectTimeout = 5 * time.Second
apiUpTimeout = 20 * time.Second apiUpTimeout = 20 * time.Second
) )
type apiForwardingState int
const (
noForwarding apiForwardingState = iota
claimUnsupported
notInstalled
machineLocal
dockerGlobal
)
type HyperVMachine struct { type HyperVMachine struct {
// ConfigPath is the fully qualified path to the configuration file // ConfigPath is the fully qualified path to the configuration file
ConfigPath machine.VMFile ConfigPath machine.VMFile
@ -469,7 +459,6 @@ func (m *HyperVMachine) SSH(name string, opts machine.SSHOptions) error {
} }
func (m *HyperVMachine) Start(name string, opts machine.StartOptions) error { func (m *HyperVMachine) Start(name string, opts machine.StartOptions) error {
// TODO We need to hold Start until it actually finishes booting and ignition stuff
vmm := hypervctl.NewVirtualMachineManager() vmm := hypervctl.NewVirtualMachineManager()
vm, err := vmm.GetMachine(m.Name) vm, err := vmm.GetMachine(m.Name)
if err != nil { if err != nil {
@ -583,20 +572,24 @@ func loadMacMachineFromJSON(fqConfigPath string, macMachine *HyperVMachine) erro
return json.Unmarshal(b, macMachine) return json.Unmarshal(b, macMachine)
} }
func (m *HyperVMachine) startHostNetworking() (string, apiForwardingState, error) { func (m *HyperVMachine) startHostNetworking() (string, machine.APIForwardingState, error) {
var (
forwardSock string
state machine.APIForwardingState
)
cfg, err := config.Default() cfg, err := config.Default()
if err != nil { if err != nil {
return "", noForwarding, err return "", machine.NoForwarding, err
} }
attr := new(os.ProcAttr) attr := new(os.ProcAttr)
dnr, err := os.OpenFile(os.DevNull, os.O_RDONLY, 0755) dnr, err := os.OpenFile(os.DevNull, os.O_RDONLY, 0755)
if err != nil { if err != nil {
return "", noForwarding, err return "", machine.NoForwarding, err
} }
dnw, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0755) dnw, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0755)
if err != nil { if err != nil {
return "", noForwarding, err return "", machine.NoForwarding, err
} }
defer func() { defer func() {
@ -621,8 +614,7 @@ func (m *HyperVMachine) startHostNetworking() (string, apiForwardingState, error
cmd = append(cmd, []string{"-ssh-port", fmt.Sprintf("%d", m.Port)}...) cmd = append(cmd, []string{"-ssh-port", fmt.Sprintf("%d", m.Port)}...)
cmd = append(cmd, []string{"-listen", fmt.Sprintf("vsock://%s", m.NetworkHVSock.KeyName)}...) cmd = append(cmd, []string{"-listen", fmt.Sprintf("vsock://%s", m.NetworkHVSock.KeyName)}...)
var forwardSock string cmd, forwardSock, state = m.setupAPIForwarding(cmd)
if logrus.GetLevel() == logrus.DebugLevel { if logrus.GetLevel() == logrus.DebugLevel {
cmd = append(cmd, "--debug") cmd = append(cmd, "--debug")
fmt.Println(cmd) fmt.Println(cmd)
@ -631,5 +623,44 @@ func (m *HyperVMachine) startHostNetworking() (string, apiForwardingState, error
if err != nil { if err != nil {
return "", 0, fmt.Errorf("unable to execute: %q: %w", cmd, err) return "", 0, fmt.Errorf("unable to execute: %q: %w", cmd, err)
} }
return forwardSock, noForwarding, nil return forwardSock, state, nil
}
func (m *HyperVMachine) setupAPIForwarding(cmd []string) ([]string, string, machine.APIForwardingState) {
socket, err := m.forwardSocketPath()
if err != nil {
return cmd, "", machine.NoForwarding
}
destSock := fmt.Sprintf("/run/user/%d/podman/podman.sock", m.UID)
forwardUser := "core"
if m.Rootful {
destSock = "/run/podman/podman.sock"
forwardUser = "root"
}
cmd = append(cmd, []string{"-forward-sock", socket.GetPath()}...)
cmd = append(cmd, []string{"-forward-dest", destSock}...)
cmd = append(cmd, []string{"-forward-user", forwardUser}...)
cmd = append(cmd, []string{"-forward-identity", m.IdentityPath}...)
return cmd, "", machine.MachineLocal
}
func (m *HyperVMachine) dockerSock() (string, error) {
dd, err := machine.GetDataDir(machine.HyperVVirt)
if err != nil {
return "", err
}
return filepath.Join(dd, "podman.sock"), nil
}
func (m *HyperVMachine) forwardSocketPath() (*machine.VMFile, error) {
sockName := "podman.sock"
path, err := machine.GetDataDir(machine.HyperVVirt)
if err != nil {
return nil, fmt.Errorf("Resolving data dir: %s", err.Error())
}
return machine.NewMachineFile(filepath.Join(path, sockName), &sockName)
} }

View File

@ -57,16 +57,6 @@ const (
apiUpTimeout = 20 * time.Second apiUpTimeout = 20 * time.Second
) )
type apiForwardingState int
const (
noForwarding apiForwardingState = iota
claimUnsupported
notInstalled
machineLocal
dockerGlobal
)
// NewMachine initializes an instance of a virtual machine based on the qemu // NewMachine initializes an instance of a virtual machine based on the qemu
// virtualization. // virtualization.
func (p *Virtualization) NewMachine(opts machine.InitOptions) (machine.VM, error) { func (p *Virtualization) NewMachine(opts machine.InitOptions) (machine.VM, error) {
@ -1231,24 +1221,24 @@ func (p *Virtualization) Format() machine.ImageFormat {
// startHostNetworking runs a binary on the host system that allows users // startHostNetworking runs a binary on the host system that allows users
// to set up port forwarding to the podman virtual machine // to set up port forwarding to the podman virtual machine
func (v *MachineVM) startHostNetworking() (string, apiForwardingState, error) { func (v *MachineVM) startHostNetworking() (string, machine.APIForwardingState, error) {
cfg, err := config.Default() cfg, err := config.Default()
if err != nil { if err != nil {
return "", noForwarding, err return "", machine.NoForwarding, err
} }
binary, err := cfg.FindHelperBinary(machine.ForwarderBinaryName, false) binary, err := cfg.FindHelperBinary(machine.ForwarderBinaryName, false)
if err != nil { if err != nil {
return "", noForwarding, err return "", machine.NoForwarding, err
} }
attr := new(os.ProcAttr) attr := new(os.ProcAttr)
dnr, err := os.OpenFile(os.DevNull, os.O_RDONLY, 0755) dnr, err := os.OpenFile(os.DevNull, os.O_RDONLY, 0755)
if err != nil { if err != nil {
return "", noForwarding, err return "", machine.NoForwarding, err
} }
dnw, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0755) dnw, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0755)
if err != nil { if err != nil {
return "", noForwarding, err return "", machine.NoForwarding, err
} }
defer dnr.Close() defer dnr.Close()
@ -1261,7 +1251,7 @@ func (v *MachineVM) startHostNetworking() (string, apiForwardingState, error) {
cmd = append(cmd, []string{"-ssh-port", fmt.Sprintf("%d", v.Port)}...) cmd = append(cmd, []string{"-ssh-port", fmt.Sprintf("%d", v.Port)}...)
var forwardSock string var forwardSock string
var state apiForwardingState var state machine.APIForwardingState
if !v.isIncompatible() { if !v.isIncompatible() {
cmd, forwardSock, state = v.setupAPIForwarding(cmd) cmd, forwardSock, state = v.setupAPIForwarding(cmd)
} }
@ -1277,11 +1267,11 @@ func (v *MachineVM) startHostNetworking() (string, apiForwardingState, error) {
return forwardSock, state, nil return forwardSock, state, nil
} }
func (v *MachineVM) setupAPIForwarding(cmd []string) ([]string, string, apiForwardingState) { func (v *MachineVM) setupAPIForwarding(cmd []string) ([]string, string, machine.APIForwardingState) {
socket, err := v.forwardSocketPath() socket, err := v.forwardSocketPath()
if err != nil { if err != nil {
return cmd, "", noForwarding return cmd, "", machine.NoForwarding
} }
destSock := fmt.Sprintf("/run/user/%d/podman/podman.sock", v.UID) destSock := fmt.Sprintf("/run/user/%d/podman/podman.sock", v.UID)
@ -1303,41 +1293,41 @@ func (v *MachineVM) setupAPIForwarding(cmd []string) ([]string, string, apiForwa
link, err := v.userGlobalSocketLink() link, err := v.userGlobalSocketLink()
if err != nil { if err != nil {
return cmd, socket.GetPath(), machineLocal return cmd, socket.GetPath(), machine.MachineLocal
} }
if !dockerClaimSupported() { if !dockerClaimSupported() {
return cmd, socket.GetPath(), claimUnsupported return cmd, socket.GetPath(), machine.ClaimUnsupported
} }
if !dockerClaimHelperInstalled() { if !dockerClaimHelperInstalled() {
return cmd, socket.GetPath(), notInstalled return cmd, socket.GetPath(), machine.NotInstalled
} }
if !alreadyLinked(socket.GetPath(), link) { if !alreadyLinked(socket.GetPath(), link) {
if checkSockInUse(link) { if checkSockInUse(link) {
return cmd, socket.GetPath(), machineLocal return cmd, socket.GetPath(), machine.MachineLocal
} }
_ = os.Remove(link) _ = os.Remove(link)
if err = os.Symlink(socket.GetPath(), link); err != nil { if err = os.Symlink(socket.GetPath(), link); err != nil {
logrus.Warnf("could not create user global API forwarding link: %s", err.Error()) logrus.Warnf("could not create user global API forwarding link: %s", err.Error())
return cmd, socket.GetPath(), machineLocal return cmd, socket.GetPath(), machine.MachineLocal
} }
} }
if !alreadyLinked(link, dockerSock) { if !alreadyLinked(link, dockerSock) {
if checkSockInUse(dockerSock) { if checkSockInUse(dockerSock) {
return cmd, socket.GetPath(), machineLocal return cmd, socket.GetPath(), machine.MachineLocal
} }
if !claimDockerSock() { if !claimDockerSock() {
logrus.Warn("podman helper is installed, but was not able to claim the global docker sock") logrus.Warn("podman helper is installed, but was not able to claim the global docker sock")
return cmd, socket.GetPath(), machineLocal return cmd, socket.GetPath(), machine.MachineLocal
} }
} }
return cmd, dockerSock, dockerGlobal return cmd, dockerSock, machine.DockerGlobal
} }
func (v *MachineVM) isIncompatible() bool { func (v *MachineVM) isIncompatible() bool {
@ -1471,7 +1461,7 @@ func waitAndPingAPI(sock string) {
} }
} }
func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forwardSock string, noInfo bool) { func (v *MachineVM) waitAPIAndPrintInfo(forwardState machine.APIForwardingState, forwardSock string, noInfo bool) {
suffix := "" suffix := ""
if v.Name != machine.DefaultMachineName { if v.Name != machine.DefaultMachineName {
suffix = " " + v.Name suffix = " " + v.Name
@ -1494,7 +1484,7 @@ func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forward
fmt.Fprintf(os.Stderr, "\t# cat backup.tar | podman machine ssh%s tar xvPf - \n\n", suffix) fmt.Fprintf(os.Stderr, "\t# cat backup.tar | podman machine ssh%s tar xvPf - \n\n", suffix)
} }
if forwardState == noForwarding { if forwardState == machine.NoForwarding {
return return
} }
@ -1509,12 +1499,12 @@ func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forward
} }
fmt.Printf("API forwarding listening on: %s\n", forwardSock) fmt.Printf("API forwarding listening on: %s\n", forwardSock)
if forwardState == dockerGlobal { if forwardState == machine.DockerGlobal {
fmt.Printf("Docker API clients default to this address. You do not need to set DOCKER_HOST.\n\n") fmt.Printf("Docker API clients default to this address. You do not need to set DOCKER_HOST.\n\n")
} else { } else {
stillString := "still " stillString := "still "
switch forwardState { switch forwardState {
case notInstalled: case machine.NotInstalled:
fmt.Printf("\nThe system helper service is not installed; the default Docker API socket\n") fmt.Printf("\nThe system helper service is not installed; the default Docker API socket\n")
fmt.Printf("address can't be used by podman. ") fmt.Printf("address can't be used by podman. ")
if helper := findClaimHelper(); len(helper) > 0 { if helper := findClaimHelper(); len(helper) > 0 {
@ -1522,9 +1512,9 @@ func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forward
fmt.Printf("\n\tsudo %s install\n", helper) fmt.Printf("\n\tsudo %s install\n", helper)
fmt.Printf("\tpodman machine stop%s; podman machine start%s\n\n", suffix, suffix) fmt.Printf("\tpodman machine stop%s; podman machine start%s\n\n", suffix, suffix)
} }
case machineLocal: case machine.MachineLocal:
fmt.Printf("\nAnother process was listening on the default Docker API socket address.\n") fmt.Printf("\nAnother process was listening on the default Docker API socket address.\n")
case claimUnsupported: case machine.ClaimUnsupported:
fallthrough fallthrough
default: default:
stillString = "" stillString = ""