Breakup AppleHV machine funcs

The functions for AppleHV's VM interface implementation (machine.go) had
quite large functions. Pulls out some code that could be moved to its
own function for easier readability and maintainability.

[NO NEW TESTS NEEDED]

Signed-off-by: Jake Correnti <jakecorrenti+github@proton.me>
This commit is contained in:
Jake Correnti 2023-07-24 10:19:04 -04:00
parent ff97a208f3
commit ff7d287fc0
1 changed files with 336 additions and 203 deletions

View File

@ -79,32 +79,21 @@ type MacMachine struct {
GvProxySock machine.VMFile
}
func (m *MacMachine) Init(opts machine.InitOptions) (bool, error) {
var (
key string
mounts []machine.Mount
virtiofsMnts []machine.VirtIoFs
)
dataDir, err := machine.GetDataDir(machine.AppleHvVirt)
if err != nil {
return false, err
}
cfg, err := config.Default()
if err != nil {
return false, err
}
// acquireVMImage determines if the image is already in a FCOS stream. If so,
// retrives the image path of the uncompressed file. Otherwise, the user has
// provided an alternative image, so we set the image path and download the image.
func (m *MacMachine) acquireVMImage(opts machine.InitOptions, dataDir string) error {
// Acquire the image
switch opts.ImagePath {
case machine.Testing.String(), machine.Next.String(), machine.Stable.String(), "":
g, err := machine.NewGenericDownloader(machine.HyperVVirt, opts.Name, opts.ImagePath)
g, err := machine.NewGenericDownloader(vmtype, opts.Name, opts.ImagePath)
if err != nil {
return false, err
return err
}
imagePath, err := machine.NewMachineFile(g.Get().GetLocalUncompressedFile(dataDir), nil)
if err != nil {
return false, err
return err
}
m.ImagePath = *imagePath
default:
@ -113,87 +102,81 @@ func (m *MacMachine) Init(opts machine.InitOptions) (bool, error) {
m.ImageStream = "custom"
g, err := machine.NewGenericDownloader(vmtype, m.Name, opts.ImagePath)
if err != nil {
return false, err
return err
}
imagePath, err := machine.NewMachineFile(g.Get().LocalUncompressedFile, nil)
if err != nil {
return false, err
return err
}
m.ImagePath = *imagePath
if err := machine.DownloadImage(g); err != nil {
return false, err
return err
}
}
return nil
}
logPath, err := machine.NewMachineFile(filepath.Join(dataDir, fmt.Sprintf("%s.log", m.Name)), nil)
if err != nil {
return false, err
}
m.LogPath = *logPath
runtimeDir, err := m.getRuntimeDir()
if err != nil {
return false, err
}
readySocket, err := machine.NewMachineFile(filepath.Join(runtimeDir, fmt.Sprintf("%s_ready.sock", m.Name)), nil)
if err != nil {
return false, err
}
// setGVProxyInfo sets the VM's gvproxy pid and socket files
func (m *MacMachine) setGVProxyInfo(runtimeDir string) error {
gvProxyPid, err := machine.NewMachineFile(filepath.Join(runtimeDir, "gvproxy.pid"), nil)
if err != nil {
return false, err
return err
}
gvProxySock, err := machine.NewMachineFile(filepath.Join(runtimeDir, "gvproxy.sock"), nil)
if err != nil {
return false, err
return err
}
m.GvProxyPid = *gvProxyPid
m.GvProxySock = *gvProxySock
return nil
}
// setVfkitInfo stores the default devices, sets the vfkit endpoint, and
// locates/stores the path to the binary
func (m *MacMachine) setVfkitInfo(cfg *config.Config, readySocket machine.VMFile) error {
defaultDevices, err := getDefaultDevices(m.ImagePath.GetPath(), m.LogPath.GetPath(), readySocket.GetPath())
if err != nil {
return false, err
return err
}
// Store VFKit stuffs
vfkitPath, err := cfg.FindHelperBinary("vfkit", false)
if err != nil {
return false, err
return err
}
vfkitBinaryPath, err := machine.NewMachineFile(vfkitPath, nil)
if err != nil {
return false, err
return err
}
m.ReadySocket = *readySocket
m.GvProxyPid = *gvProxyPid
m.GvProxySock = *gvProxySock
m.Vfkit.VirtualMachine.Devices = defaultDevices
m.Vfkit.Endpoint = defaultVFKitEndpoint
m.Vfkit.VfkitBinaryPath = vfkitBinaryPath
m.IdentityPath = util.GetIdentityPath(m.Name)
m.Rootful = opts.Rootful
m.RemoteUsername = opts.Username
m.UID = os.Getuid()
sshPort, err := utils.GetRandomPort()
if err != nil {
return false, err
}
m.Port = sshPort
return nil
}
// addMountsToVM converts the volumes passed through the CLI to virtio-fs mounts
// and adds them to the machine
func (m *MacMachine) addMountsToVM(opts machine.InitOptions, virtiofsMnts *[]machine.VirtIoFs) error {
mounts := []machine.Mount{}
for _, volume := range opts.Volumes {
source, target, _, readOnly, err := machine.ParseVolumeFromPath(volume)
if err != nil {
return false, err
return err
}
mnt := machine.NewVirtIoFsMount(source, target, readOnly)
virtiofsMnts = append(virtiofsMnts, mnt)
*virtiofsMnts = append(*virtiofsMnts, mnt)
mounts = append(mounts, mnt.ToMount())
}
m.Mounts = mounts
return nil
}
func (m *MacMachine) addSSHConnectionsToPodmanSocket(opts machine.InitOptions) error {
if len(opts.IgnitionPath) < 1 {
// TODO localhost needs to be restored here
uri := machine.SSHRemoteConnection.MakeSSHURL("localhost", fmt.Sprintf("/run/user/%d/podman/podman.sock", m.UID), strconv.Itoa(m.Port), m.RemoteUsername)
@ -211,13 +194,123 @@ func (m *MacMachine) Init(opts machine.InitOptions) (bool, error) {
for i := 0; i < 2; i++ {
if err := machine.AddConnection(&uris[i], names[i], identity, opts.IsDefault && i == 0); err != nil {
return false, err
return err
}
}
} else {
fmt.Println("An ignition path was provided. No SSH connection was added to Podman")
}
return nil
}
// writeIgnitionConfigFile generates the ignition config and writes it to the filesystem
func (m *MacMachine) writeIgnitionConfigFile(opts machine.InitOptions, key string, virtiofsMnts *[]machine.VirtIoFs) error {
// Write the ignition file
ign := machine.DynamicIgnition{
Name: opts.Username,
Key: key,
VMName: m.Name,
VMType: machine.AppleHvVirt,
TimeZone: opts.TimeZone,
WritePath: m.IgnitionFile.GetPath(),
UID: m.UID,
Rootful: m.Rootful,
}
if err := ign.GenerateIgnitionConfig(); err != nil {
return 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
ready := `[Unit]
Requires=dev-virtio\\x2dports-%s.device
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:1025'
[Install]
RequiredBy=default.target
`
readyUnit := machine.Unit{
Enabled: machine.BoolToPtr(true),
Name: "ready.service",
Contents: machine.StrToPtr(fmt.Sprintf(ready, "vsock")),
}
virtiofsUnits := generateSystemDFilesForVirtiofsMounts(*virtiofsMnts)
ign.Cfg.Systemd.Units = append(ign.Cfg.Systemd.Units, readyUnit)
ign.Cfg.Systemd.Units = append(ign.Cfg.Systemd.Units, virtiofsUnits...)
return ign.Write()
}
func (m *MacMachine) Init(opts machine.InitOptions) (bool, error) {
var (
key string
virtiofsMnts []machine.VirtIoFs
)
dataDir, err := machine.GetDataDir(machine.AppleHvVirt)
if err != nil {
return false, err
}
cfg, err := config.Default()
if err != nil {
return false, err
}
if err := m.acquireVMImage(opts, dataDir); err != nil {
return false, err
}
logPath, err := machine.NewMachineFile(filepath.Join(dataDir, fmt.Sprintf("%s.log", m.Name)), nil)
if err != nil {
return false, err
}
m.LogPath = *logPath
runtimeDir, err := m.getRuntimeDir()
if err != nil {
return false, err
}
readySocket, err := machine.NewMachineFile(filepath.Join(runtimeDir, fmt.Sprintf("%s_ready.sock", m.Name)), nil)
if err != nil {
return false, err
}
m.ReadySocket = *readySocket
if err := m.setGVProxyInfo(runtimeDir); err != nil {
return false, err
}
if err := m.setVfkitInfo(cfg, m.ReadySocket); err != nil {
return false, err
}
m.IdentityPath = util.GetIdentityPath(m.Name)
m.Rootful = opts.Rootful
m.RemoteUsername = opts.Username
m.UID = os.Getuid()
sshPort, err := utils.GetRandomPort()
if err != nil {
return false, err
}
m.Port = sshPort
if err := m.addMountsToVM(opts, &virtiofsMnts); err != nil {
return false, err
}
if err := m.addSSHConnectionsToPodmanSocket(opts); err != nil {
return false, err
}
// Until the disk resize can be fixed, we ignore it
if err := m.resizeDisk(opts.DiskSize); err != nil && !errors.Is(err, define.ErrNotImplemented) {
return false, err
@ -243,52 +336,8 @@ func (m *MacMachine) Init(opts machine.InitOptions) (bool, error) {
return false, os.WriteFile(m.IgnitionFile.GetPath(), inputIgnition, 0644)
}
// TODO Ignition stuff goes here
// Write the ignition file
ign := machine.DynamicIgnition{
Name: opts.Username,
Key: key,
VMName: m.Name,
VMType: machine.AppleHvVirt,
TimeZone: opts.TimeZone,
WritePath: m.IgnitionFile.GetPath(),
UID: m.UID,
Rootful: m.Rootful,
}
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
ready := `[Unit]
Requires=dev-virtio\\x2dports-%s.device
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:1025'
[Install]
RequiredBy=default.target
`
readyUnit := machine.Unit{
Enabled: machine.BoolToPtr(true),
Name: "ready.service",
Contents: machine.StrToPtr(fmt.Sprintf(ready, "vsock")),
}
virtiofsUnits := generateSystemDFilesForVirtiofsMounts(virtiofsMnts)
ign.Cfg.Systemd.Units = append(ign.Cfg.Systemd.Units, readyUnit)
ign.Cfg.Systemd.Units = append(ign.Cfg.Systemd.Units, virtiofsUnits...)
if err := ign.Write(); err != nil {
return false, err
}
return true, nil
err = m.writeIgnitionConfigFile(opts, key, &virtiofsMnts)
return err == nil, err
}
func (m *MacMachine) Inspect() (*machine.InspectInfo, error) {
@ -321,24 +370,9 @@ func (m *MacMachine) Inspect() (*machine.InspectInfo, error) {
return &ii, nil
}
func (m *MacMachine) Remove(name string, opts machine.RemoveOptions) (string, func() error, error) {
var (
files []string
)
vmState, err := m.Vfkit.state()
if err != nil {
return "", nil, err
}
if vmState == machine.Running {
if !opts.Force {
return "", nil, fmt.Errorf("invalid state: %s is running", m.Name)
}
if err := m.Vfkit.stop(true, true); err != nil {
return "", nil, err
}
}
// collectFilesToDestroy retrieves the files that will be destroyed by `Remove`
func (m *MacMachine) collectFilesToDestroy(opts machine.RemoveOptions) []string {
files := []string{}
if !opts.SaveKeys {
files = append(files, m.IdentityPath, m.IdentityPath+".pub")
}
@ -351,6 +385,45 @@ func (m *MacMachine) Remove(name string, opts machine.RemoveOptions) (string, fu
}
files = append(files, m.ConfigPath.GetPath())
return files
}
// removeFilesAndConnections removes any files and connections associated with
// the machine during `Remove`
func (m *MacMachine) removeFilesAndConnections(files []string) {
for _, f := range files {
if err := os.Remove(f); err != nil && !errors.Is(err, os.ErrNotExist) {
logrus.Error(err)
}
}
if err := machine.RemoveConnections(m.Name); err != nil {
logrus.Error(err)
}
if err := machine.RemoveConnections(m.Name + "-root"); err != nil {
logrus.Error(err)
}
}
func (m *MacMachine) Remove(name string, opts machine.RemoveOptions) (string, func() error, error) {
var (
files []string
)
vmState, err := m.Vfkit.state()
if err != nil {
return "", nil, err
}
if vmState == machine.Running {
if !opts.Force {
return "", nil, fmt.Errorf("invalid state: %s is running", m.Name)
}
if err := m.Vfkit.stop(true, true); err != nil {
return "", nil, err
}
}
files = m.collectFilesToDestroy(opts)
confirmationMessage := "\nThe following files will be deleted:\n\n"
for _, msg := range files {
@ -359,18 +432,7 @@ func (m *MacMachine) Remove(name string, opts machine.RemoveOptions) (string, fu
confirmationMessage += "\n"
return confirmationMessage, func() error {
for _, f := range files {
if err := os.Remove(f); err != nil && !errors.Is(err, os.ErrNotExist) {
logrus.Error(err)
}
}
if err := machine.RemoveConnections(m.Name); err != nil {
logrus.Error(err)
}
if err := machine.RemoveConnections(m.Name + "-root"); err != nil {
logrus.Error(err)
}
m.removeFilesAndConnections(files)
// TODO We will need something like this for applehv too i think
/*
// Remove the HVSOCK for networking
@ -451,6 +513,73 @@ func (m *MacMachine) SSH(name string, opts machine.SSHOptions) error {
return machine.CommonSSH(username, m.IdentityPath, m.Name, m.Port, opts.Args)
}
// deleteIgnitionSocket retrieves the ignition socket, deletes it, and returns a
// pointer to the `VMFile`
func (m *MacMachine) deleteIgnitionSocket() (*machine.VMFile, error) {
ignitionSocket, err := m.getIgnitionSock()
if err != nil {
return nil, err
}
if err := ignitionSocket.Delete(); err != nil {
return nil, err
}
return ignitionSocket, nil
}
// getIgnitionVsockDeviceAsCLI retrieves the ignition vsock device and converts
// it to a cmdline format
func getIgnitionVsockDeviceAsCLI(ignitionSocketPath string) ([]string, error) {
ignitionVsockDevice, err := getIgnitionVsockDevice(ignitionSocketPath)
if err != nil {
return nil, err
}
// Convert the device into cli args
ignitionVsockDeviceCLI, err := ignitionVsockDevice.ToCmdLine()
if err != nil {
return nil, err
}
return ignitionVsockDeviceCLI, nil
}
// getDebugDevicesCMDArgs retrieves the debug devices and converts them to a
// cmdline format
func getDebugDevicesCMDArgs() ([]string, error) {
args := []string{}
debugDevices, err := getDebugDevices()
if err != nil {
return nil, err
}
for _, debugDevice := range debugDevices {
debugCli, err := debugDevice.ToCmdLine()
if err != nil {
return nil, err
}
args = append(args, debugCli...)
}
return args, nil
}
// getVfKitEndpointCMDArgs converts the vfkit endpoint to a cmdline format
func getVfKitEndpointCMDArgs(endpoint string) ([]string, error) {
restEndpoint, err := vfRest.NewEndpoint(endpoint)
if err != nil {
return nil, err
}
return restEndpoint.ToCmdLine()
}
// addVolumesToVfKit adds the VM's mounts to vfkit's devices
func (m *MacMachine) addVolumesToVfKit() error {
for _, vol := range m.Mounts {
virtfsDevice, err := vfConfig.VirtioFsNew(vol.Source, vol.Tag)
if err != nil {
return err
}
m.Vfkit.VirtualMachine.Devices = append(m.Vfkit.VirtualMachine.Devices, virtfsDevice)
}
return nil
}
func (m *MacMachine) Start(name string, opts machine.StartOptions) error {
var ignitionSocket *machine.VMFile
@ -458,6 +587,7 @@ func (m *MacMachine) Start(name string, opts machine.StartOptions) error {
if err != nil {
return err
}
if st == machine.Running {
return machine.ErrVMAlreadyRunning
}
@ -484,12 +614,8 @@ func (m *MacMachine) Start(name string, opts machine.StartOptions) error {
m.Vfkit.VirtualMachine.Devices = append(m.Vfkit.VirtualMachine.Devices, netDevice)
for _, vol := range m.Mounts {
virtfsDevice, err := vfConfig.VirtioFsNew(vol.Source, vol.Tag)
if err != nil {
return err
}
m.Vfkit.VirtualMachine.Devices = append(m.Vfkit.VirtualMachine.Devices, virtfsDevice)
if err := m.addVolumesToVfKit(); err != nil {
return err
}
// To start the VM, we need to call vfkit
@ -499,55 +625,41 @@ func (m *MacMachine) Start(name string, opts machine.StartOptions) error {
return err
}
restEndpoint, err := vfRest.NewEndpoint(m.Vfkit.Endpoint)
vfkitEndpointArgs, err := getVfKitEndpointCMDArgs(m.Vfkit.Endpoint)
if err != nil {
return err
}
restArgs, err := restEndpoint.ToCmdLine()
if err != nil {
return err
}
cmd.Args = append(cmd.Args, restArgs...)
cmd.Args = append(cmd.Args, vfkitEndpointArgs...)
firstBoot, err := m.isFirstBoot()
if err != nil {
return err
}
if firstBoot {
// If this is the first boot of the vm, we need to add the vsock
// device to vfkit so we can inject the ignition file
ignitionSocket, err = m.getIgnitionSock()
ignitionSocket, err = m.deleteIgnitionSocket()
if err != nil {
return err
}
if err := ignitionSocket.Delete(); err != nil {
return err
}
ignitionVsockDevice, err := getIgnitionVsockDevice(ignitionSocket.GetPath())
ignitionVsockDeviceCLI, err := getIgnitionVsockDeviceAsCLI(ignitionSocket.GetPath())
if err != nil {
return err
}
// Convert the device into cli args
ignitionVsockDeviceCli, err := ignitionVsockDevice.ToCmdLine()
if err != nil {
return err
}
cmd.Args = append(cmd.Args, ignitionVsockDeviceCli...)
cmd.Args = append(cmd.Args, ignitionVsockDeviceCLI...)
}
if logrus.IsLevelEnabled(logrus.DebugLevel) {
debugDevices, err := getDebugDevices()
debugDevArgs, err := getDebugDevicesCMDArgs()
if err != nil {
return err
}
for _, debugDevice := range debugDevices {
debugCli, err := debugDevice.ToCmdLine()
if err != nil {
return err
}
cmd.Args = append(cmd.Args, debugCli...)
}
cmd.Args = append(cmd.Args, debugDevArgs...)
cmd.Args = append(cmd.Args, "--gui") // add command line switch to pop the gui open
}
cmd.ExtraFiles = []*os.File{ioEater, ioEater, ioEater}
fmt.Println(cmd.Args)
@ -566,14 +678,17 @@ func (m *MacMachine) Start(name string, opts machine.StartOptions) error {
logrus.Debug("ignition vsock server exited")
}()
}
if err := m.ReadySocket.Delete(); err != nil {
return err
}
logrus.Debugf("listening for ready on: %s", m.ReadySocket.GetPath())
readyListen, err := net.Listen("unix", m.ReadySocket.GetPath())
if err != nil {
return err
}
logrus.Debug("waiting for ready notification")
var conn net.Conn
readyChan := make(chan error)
@ -585,6 +700,7 @@ func (m *MacMachine) Start(name string, opts machine.StartOptions) error {
_, err = bufio.NewReader(conn).ReadString('\n')
readyChan <- err
}()
if err := cmd.Start(); err != nil {
return err
}
@ -598,6 +714,7 @@ func (m *MacMachine) Start(name string, opts machine.StartOptions) error {
if err != nil {
return err
}
logrus.Debug("ready notification received")
m.waitAPIAndPrintInfo(forwardState, forwardSock, opts.NoInfo)
return nil
@ -611,41 +728,45 @@ func (m *MacMachine) State(_ bool) (machine.Status, error) {
return vmStatus, nil
}
// cleanupGVProxy finds the gvproxy process, kills it, and deletes the
// pidfile
func (m *MacMachine) cleanupGVProxy() {
gvPid, err := m.GvProxyPid.Read()
if err != nil {
logrus.Error(fmt.Errorf("unable to read gvproxy pid file %s: %v", m.GvProxyPid.GetPath(), err))
return
}
proxyPid, err := strconv.Atoi(string(gvPid))
if err != nil {
logrus.Error(fmt.Errorf("unable to convert pid to integer: %v", err))
return
}
proxyProc, err := os.FindProcess(proxyPid)
if proxyProc == nil && err != nil {
logrus.Error("unable to find process: %v", err)
return
}
if err := proxyProc.Kill(); err != nil {
logrus.Error("unable to kill gvproxy: %v", err)
return
}
// gvproxy does not clean up its pid file on exit
if err := m.GvProxyPid.Delete(); err != nil {
logrus.Error("unable to delete gvproxy pid file: %v", err)
}
}
func (m *MacMachine) Stop(name string, opts machine.StopOptions) error {
vmState, err := m.State(false)
if err != nil {
return err
}
if vmState != machine.Running {
return machine.ErrWrongState
}
defer func() {
// I think "soft" errors here is OK
gvPid, err := m.GvProxyPid.Read()
if err != nil {
logrus.Error(fmt.Errorf("unable to read gvproxy pid file %s: %v", m.GvProxyPid.GetPath(), err))
return
}
proxyPid, err := strconv.Atoi(string(gvPid))
if err != nil {
logrus.Error(fmt.Errorf("unable to convert pid to integer: %v", err))
return
}
proxyProc, err := os.FindProcess(proxyPid)
if proxyProc == nil && err != nil {
logrus.Error("unable to find process: %v", err)
return
}
if err := proxyProc.Kill(); err != nil {
logrus.Error("unable to kill gvproxy: %v", err)
return
}
// gvproxy does not clean up its pid file on exit
if err := m.GvProxyPid.Delete(); err != nil {
logrus.Error("unable to delete gvproxy pid file: %v", err)
}
}()
defer m.cleanupGVProxy()
return m.Vfkit.stop(false, true)
}
@ -655,6 +776,7 @@ func (m *MacMachine) Stop(name string, opts machine.StopOptions) error {
func getVMConfigPath(configDir, vmName string) string {
return filepath.Join(configDir, fmt.Sprintf("%s.json", vmName))
}
func (m *MacMachine) loadFromFile() (*MacMachine, error) {
if len(m.Name) < 1 {
return nil, errors.New("encountered machine with no name")
@ -758,6 +880,26 @@ func getVMInfos() ([]*machine.ListResponse, error) {
return listed, err
}
// setupStartHostNetworkingCmd generates the cmd that will be used to start the
// host networking. Includes the ssh port, gvproxy pid file, gvproxy socket, and
// a debug flag depending on the logrus log level
func (m *MacMachine) setupStartHostNetworkingCmd(gvProxyBinary, forwardSock string, state machine.APIForwardingState) []string {
cmd := []string{gvProxyBinary}
// Add the ssh port
cmd = append(cmd, []string{"-ssh-port", fmt.Sprintf("%d", m.Port)}...)
// Add pid file
cmd = append(cmd, "-pid-file", m.GvProxyPid.GetPath())
// Add vfkit proxy listen
cmd = append(cmd, "-listen-vfkit", fmt.Sprintf("unixgram://%s", m.GvProxySock.GetPath()))
cmd, forwardSock, state = m.setupAPIForwarding(cmd)
if logrus.GetLevel() == logrus.DebugLevel {
cmd = append(cmd, "--debug")
fmt.Println(cmd)
}
return cmd
}
func (m *MacMachine) startHostNetworking(ioEater *os.File) (string, machine.APIForwardingState, error) {
var (
forwardSock string
@ -792,6 +934,7 @@ func (m *MacMachine) startHostNetworking(ioEater *os.File) (string, machine.APIF
if err != nil {
return "", machine.NoForwarding, err
}
attr := new(os.ProcAttr)
gvproxy, err := cfg.FindHelperBinary("gvproxy", false)
if err != nil {
@ -799,18 +942,7 @@ func (m *MacMachine) startHostNetworking(ioEater *os.File) (string, machine.APIF
}
attr.Files = []*os.File{ioEater, ioEater, ioEater}
cmd := []string{gvproxy}
// Add the ssh port
cmd = append(cmd, []string{"-ssh-port", fmt.Sprintf("%d", m.Port)}...)
// Add pid file
cmd = append(cmd, "-pid-file", m.GvProxyPid.GetPath())
// Add vfkit proxy listen
cmd = append(cmd, "-listen-vfkit", fmt.Sprintf("unixgram://%s", m.GvProxySock.GetPath()))
cmd, forwardSock, state = m.setupAPIForwarding(cmd)
if logrus.GetLevel() == logrus.DebugLevel {
cmd = append(cmd, "--debug")
fmt.Println(cmd)
}
cmd := m.setupStartHostNetworkingCmd(gvproxy, forwardSock, state)
_, err = os.StartProcess(cmd[0], cmd, attr)
if err != nil {
@ -843,6 +975,7 @@ func AppleHVSSH(username, identityPath, name string, sshPort int, inputArgs []st
return cmd.Run()
}
func (m *MacMachine) setupAPIForwarding(cmd []string) ([]string, string, machine.APIForwardingState) {
socket, err := m.forwardSocketPath()
if err != nil {