Skip to content

Commit

Permalink
Merge pull request #18167 from baude/hypervvsock
Browse files Browse the repository at this point in the history
Add support for HVSOCK on hyperv
  • Loading branch information
openshift-merge-robot authored Apr 17, 2023
2 parents b7fc57c + f488d98 commit ef4dbc2
Show file tree
Hide file tree
Showing 6 changed files with 403 additions and 69 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.18

require (
github.com/BurntSushi/toml v1.2.1
github.com/Microsoft/go-winio v0.6.0
github.com/blang/semver/v4 v4.0.0
github.com/buger/goterm v1.0.4
github.com/checkpoint-restore/checkpointctl v0.1.0
Expand Down Expand Up @@ -74,7 +75,6 @@ require (

require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/Microsoft/hcsshim v0.10.0-rc.7 // indirect
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
Expand Down
9 changes: 7 additions & 2 deletions pkg/machine/hyperv/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package hyperv
import (
"encoding/json"
"errors"
"github.com/sirupsen/logrus"
"io/fs"
"os"
"path/filepath"
Expand All @@ -15,6 +14,7 @@ import (
"github.com/containers/libhvee/pkg/hypervctl"
"github.com/containers/podman/v4/pkg/machine"
"github.com/docker/go-units"
"github.com/sirupsen/logrus"
)

type Virtualization struct {
Expand Down Expand Up @@ -178,7 +178,6 @@ func (v Virtualization) NewMachine(opts machine.InitOptions) (machine.VM, error)
return nil, err
}
return v.LoadVMByName(opts.Name)

}

func (v Virtualization) RemoveAndCleanMachines() error {
Expand Down Expand Up @@ -221,6 +220,12 @@ func (v Virtualization) RemoveAndCleanMachines() error {
if err := vm.Remove(mm.ImagePath.GetPath()); err != nil {
prevErr = handlePrevError(err, prevErr)
}
if err := mm.ReadyHVSock.Remove(); err != nil {
prevErr = handlePrevError(err, prevErr)
}
if err := mm.NetworkHVSock.Remove(); err != nil {
prevErr = handlePrevError(err, prevErr)
}
}

// Nuke the config and dataDirs
Expand Down
83 changes: 64 additions & 19 deletions pkg/machine/hyperv/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,8 @@ const (
)

type HyperVMachine struct {
// copied from qemu, cull and add as needed

// ConfigPath is the fully qualified path to the configuration file
ConfigPath machine.VMFile
// The command line representation of the qemu command
//CmdLine []string
// HostUser contains info about host user
machine.HostUser
// ImageConfig describes the bootable image
Expand All @@ -70,14 +66,10 @@ type HyperVMachine struct {
Mounts []machine.Mount
// Name of VM
Name string
// PidFilePath is the where the Proxy PID file lives
//PidFilePath machine.VMFile
// VMPidFilePath is the where the VM PID file lives
//VMPidFilePath machine.VMFile
// QMPMonitor is the qemu monitor object for sending commands
//QMPMonitor Monitor
// NetworkVSock is for the user networking
NetworkHVSock HVSockRegistryEntry
// ReadySocket tells host when vm is booted
ReadySocket machine.VMFile
ReadyHVSock HVSockRegistryEntry
// ResourceConfig is physical attrs of the VM
machine.ResourceConfig
// SSHConfig for accessing the remote vm
Expand All @@ -95,6 +87,18 @@ func (m *HyperVMachine) Init(opts machine.InitOptions) (bool, error) {
key string
)

// Add the network and ready sockets to the Windows registry
networkHVSock, err := NewHVSockRegistryEntry(m.Name, Network)
if err != nil {
return false, err
}
eventHVSocket, err := NewHVSockRegistryEntry(m.Name, Events)
if err != nil {
return false, err
}
m.NetworkHVSock = *networkHVSock
m.ReadyHVSock = *eventHVSocket

sshDir := filepath.Join(homedir.Get(), ".ssh")
m.IdentityPath = filepath.Join(sshDir, m.Name)

Expand Down Expand Up @@ -170,12 +174,39 @@ func (m *HyperVMachine) Init(opts machine.InitOptions) (bool, error) {
Name: user,
Key: key,
VMName: m.Name,
VMType: machine.HyperVVirt,
TimeZone: opts.TimeZone,
WritePath: m.IgnitionFile.GetPath(),
UID: m.UID,
}

if err := machine.NewIgnitionFile(ign, machine.HyperVVirt); err != nil {
if err := ign.GenerateIgnitionConfig(); err != nil {
return false, err
}

// ready is a unit file that sets up the virtual serial device
// where when the VM is done configuring, it will send an ack
// so a listening host knows it can being interacting with it
//
// VSOCK-CONNECT:2 <- shortcut to connect to the hostvm
ready := `[Unit]
After=remove-moby.service sshd.socket sshd.service
OnFailure=emergency.target
OnFailureJobMode=isolate
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/sh -c '/usr/bin/echo Ready | socat - VSOCK-CONNECT:2:%d'
[Install]
RequiredBy=default.target
`
readyUnit := machine.Unit{
Enabled: machine.BoolToPtr(true),
Name: "ready.service",
Contents: machine.StrToPtr(fmt.Sprintf(ready, m.ReadyHVSock.Port)),
}
ign.Cfg.Systemd.Units = append(ign.Cfg.Systemd.Units, readyUnit)
if err := ign.Write(); err != nil {
return false, err
}
// The ignition file has been written. We now need to
Expand Down Expand Up @@ -259,12 +290,6 @@ func (m *HyperVMachine) Remove(_ string, opts machine.RemoveOptions) (string, fu
files = append(files, diskPath)
}

if err := machine.RemoveConnection(m.Name); err != nil {
logrus.Error(err)
}
if err := machine.RemoveConnection(m.Name + "-root"); err != nil {
logrus.Error(err)
}
files = append(files, getVMConfigPath(m.ConfigPath.GetPath(), m.Name))
confirmationMessage := "\nThe following files will be deleted:\n\n"
for _, msg := range files {
Expand All @@ -278,6 +303,22 @@ func (m *HyperVMachine) Remove(_ string, opts machine.RemoveOptions) (string, fu
logrus.Error(err)
}
}
if err := machine.RemoveConnection(m.Name); err != nil {
logrus.Error(err)
}
if err := machine.RemoveConnection(m.Name + "-root"); err != nil {
logrus.Error(err)
}

// Remove the HVSOCK for networking
if err := m.NetworkHVSock.Remove(); err != nil {
logrus.Errorf("unable to remove registry entry for %s: %q", m.NetworkHVSock.KeyName, err)
}

// Remove the HVSOCK for events
if err := m.ReadyHVSock.Remove(); err != nil {
logrus.Errorf("unable to remove registry entry for %s: %q", m.NetworkHVSock.KeyName, err)
}
return vm.Remove(diskPath)
}, nil
}
Expand Down Expand Up @@ -360,7 +401,11 @@ func (m *HyperVMachine) Start(name string, opts machine.StartOptions) error {
if vm.State() != hypervctl.Disabled {
return hypervctl.ErrMachineStateInvalid
}
return vm.Start()
if err := vm.Start(); err != nil {
return err
}
// Wait on notification from the guest
return m.ReadyHVSock.Listen()
}

func (m *HyperVMachine) State(_ bool) (machine.Status, error) {
Expand Down
Loading

0 comments on commit ef4dbc2

Please sign in to comment.