Using vmconnect to display gui for hyper-v
vmconnect.exe comes as part of Hyper-V and is the tool used by Hyper-V Manager to connect with a virtual machine. This commits sets behaviour the same as virtualbox and vmware to display the virtual machine connection unless headless is set in the template.
This commit is contained in:
parent
132dfa7c86
commit
fc734b6bd9
|
@ -1,5 +1,9 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// A driver is able to talk to HyperV and perform certain
|
||||
// operations with it. Some of the operations on here may seem overly
|
||||
// specific, but they were built specifically in mind to handle features
|
||||
|
@ -109,4 +113,10 @@ type Driver interface {
|
|||
MountFloppyDrive(string, string) error
|
||||
|
||||
UnmountFloppyDrive(string) error
|
||||
|
||||
// Connect connects to a VM specified by the name given.
|
||||
Connect(string) context.CancelFunc
|
||||
|
||||
// Disconnect disconnects to a VM specified by the context cancel function.
|
||||
Disconnect(context.CancelFunc)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type DriverMock struct {
|
||||
IsRunning_Called bool
|
||||
IsRunning_VmName string
|
||||
|
@ -240,6 +244,13 @@ type DriverMock struct {
|
|||
UnmountFloppyDrive_Called bool
|
||||
UnmountFloppyDrive_VmName string
|
||||
UnmountFloppyDrive_Err error
|
||||
|
||||
Connect_Called bool
|
||||
Connect_VmName string
|
||||
Connect_Cancel context.CancelFunc
|
||||
|
||||
Disconnect_Called bool
|
||||
Disconnect_Cancel context.CancelFunc
|
||||
}
|
||||
|
||||
func (d *DriverMock) IsRunning(vmName string) (bool, error) {
|
||||
|
@ -553,3 +564,14 @@ func (d *DriverMock) UnmountFloppyDrive(vmName string) error {
|
|||
d.UnmountFloppyDrive_VmName = vmName
|
||||
return d.UnmountFloppyDrive_Err
|
||||
}
|
||||
|
||||
func (d *DriverMock) Connect(vmName string) context.CancelFunc {
|
||||
d.Connect_Called = true
|
||||
d.Connect_VmName = vmName
|
||||
return d.Connect_Cancel
|
||||
}
|
||||
|
||||
func (d *DriverMock) Disconnect(cancel context.CancelFunc) {
|
||||
d.Disconnect_Called = true
|
||||
d.Disconnect_Cancel = cancel
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"runtime"
|
||||
|
@ -347,3 +348,14 @@ func (d *HypervPS4Driver) verifyHypervPermissions() error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Connect connects to a VM specified by the name given.
|
||||
func (d *HypervPS4Driver) Connect(vmName string) context.CancelFunc {
|
||||
return hyperv.ConnectVirtualMachine(vmName)
|
||||
}
|
||||
|
||||
// Disconnect disconnects to a VM specified by calling the context cancel function returned
|
||||
// from Connect.
|
||||
func (d *HypervPS4Driver) Disconnect(cancel context.CancelFunc) {
|
||||
hyperv.DisconnectVirtualMachine(cancel)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ import (
|
|||
)
|
||||
|
||||
type StepRun struct {
|
||||
vmName string
|
||||
Headless bool
|
||||
vmName string
|
||||
}
|
||||
|
||||
func (s *StepRun) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
|
@ -29,6 +30,11 @@ func (s *StepRun) Run(_ context.Context, state multistep.StateBag) multistep.Ste
|
|||
|
||||
s.vmName = vmName
|
||||
|
||||
if !s.Headless {
|
||||
ui.Say("Connecting to vmconnect...")
|
||||
cancel := driver.Connect(vmName)
|
||||
state.Put("guiCancelFunc", cancel)
|
||||
}
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
@ -39,6 +45,12 @@ func (s *StepRun) Cleanup(state multistep.StateBag) {
|
|||
|
||||
driver := state.Get("driver").(Driver)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
guiCancelFunc := state.Get("guiCancelFunc").(context.CancelFunc)
|
||||
|
||||
if guiCancelFunc != nil {
|
||||
ui.Say("Disconnecting from vmconnect...")
|
||||
guiCancelFunc()
|
||||
}
|
||||
|
||||
if running, _ := driver.IsRunning(s.vmName); running {
|
||||
if err := driver.Stop(s.vmName); err != nil {
|
||||
|
|
|
@ -115,6 +115,8 @@ type Config struct {
|
|||
// Create the VM with a Fixed VHD format disk instead of Dynamic VHDX
|
||||
FixedVHD bool `mapstructure:"use_fixed_vhd_format"`
|
||||
|
||||
Headless bool `mapstructure:"headless"`
|
||||
|
||||
ctx interpolate.Context
|
||||
}
|
||||
|
||||
|
@ -427,7 +429,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
SwitchVlanId: b.config.SwitchVlanId,
|
||||
},
|
||||
|
||||
&hypervcommon.StepRun{},
|
||||
&hypervcommon.StepRun{
|
||||
Headless: b.config.Headless,
|
||||
},
|
||||
|
||||
&hypervcommon.StepTypeBootCommand{
|
||||
BootCommand: b.config.FlatBootCommand(),
|
||||
|
|
|
@ -98,6 +98,8 @@ type Config struct {
|
|||
|
||||
SkipExport bool `mapstructure:"skip_export"`
|
||||
|
||||
Headless bool `mapstructure:"headless"`
|
||||
|
||||
ctx interpolate.Context
|
||||
}
|
||||
|
||||
|
@ -436,7 +438,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
SwitchVlanId: b.config.SwitchVlanId,
|
||||
},
|
||||
|
||||
&hypervcommon.StepRun{},
|
||||
&hypervcommon.StepRun{
|
||||
Headless: b.config.Headless,
|
||||
},
|
||||
|
||||
&hypervcommon.StepTypeBootCommand{
|
||||
BootCommand: b.config.FlatBootCommand(),
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package hyperv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -1244,3 +1246,14 @@ param([string]$vmName, [string]$scanCodes)
|
|||
err := ps.Run(script, vmName, scanCodes)
|
||||
return err
|
||||
}
|
||||
|
||||
func ConnectVirtualMachine(vmName string) context.CancelFunc {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cmd := exec.CommandContext(ctx, "vmconnect.exe", "localhost", vmName)
|
||||
cmd.Start()
|
||||
return cancel
|
||||
}
|
||||
|
||||
func DisconnectVirtualMachine(cancel context.CancelFunc) {
|
||||
cancel()
|
||||
}
|
||||
|
|
|
@ -102,6 +102,11 @@ can be configured for this builder.
|
|||
- `differencing_disk` (boolean) - If true enables differencing disks. Only the changes will be written to the new disk. This is especially useful if your
|
||||
source is a vhd/vhdx. This defaults to false.
|
||||
|
||||
- `headless` (boolean) - Packer defaults to building Hyper-V virtual
|
||||
machines by launching a GUI that shows the console of the machine
|
||||
being built. When this value is set to true, the machine will start without
|
||||
a console.
|
||||
|
||||
- `skip_export` (boolean) - If true skips VM export. If you are interested only in the vhd/vhdx files, you can enable this option. This will create
|
||||
inline disks which improves the build performance. There will not be any copying of source vhds to temp directory. This defaults to false.
|
||||
|
||||
|
|
|
@ -139,6 +139,11 @@ can be configured for this builder.
|
|||
- `guest_additions_path` (string) - The path to the iso image for guest
|
||||
additions.
|
||||
|
||||
- `headless` (boolean) - Packer defaults to building Hyper-V virtual
|
||||
machines by launching a GUI that shows the console of the machine
|
||||
being built. When this value is set to true, the machine will start without
|
||||
a console.
|
||||
|
||||
- `http_directory` (string) - Path to a directory to serve using an HTTP
|
||||
server. The files in this directory will be available over HTTP that will
|
||||
be requestable from the virtual machine. This is useful for hosting
|
||||
|
|
Loading…
Reference in New Issue