Allow configurable VNC bind IP for QEMU
This commit allows for a user configurable VNC bind IP to be used for QEMU. By default this will be 127.0.0.1, alternatively, a user can use 0.0.0.0 which will bind to all interfaces. This pull request should satisfy concerns of #3570 and #3559. It is also in-line with the functionality provided by #3566 and #3565 Signed-off-by: Ian Duffy <ian@ianduffy.ie>
This commit is contained in:
parent
7759229b9d
commit
fa273f3bea
|
@ -104,6 +104,7 @@ type Config struct {
|
|||
ShutdownCommand string `mapstructure:"shutdown_command"`
|
||||
SSHHostPortMin uint `mapstructure:"ssh_host_port_min"`
|
||||
SSHHostPortMax uint `mapstructure:"ssh_host_port_max"`
|
||||
VNCBindAddress string `mapstructure:"vnc_bind_address"`
|
||||
VNCPortMin uint `mapstructure:"vnc_port_min"`
|
||||
VNCPortMax uint `mapstructure:"vnc_port_max"`
|
||||
VMName string `mapstructure:"vm_name"`
|
||||
|
@ -194,6 +195,10 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
b.config.SSHHostPortMax = 4444
|
||||
}
|
||||
|
||||
if b.config.VNCBindAddress == "" {
|
||||
b.config.VNCBindAddress = "127.0.0.1"
|
||||
}
|
||||
|
||||
if b.config.VNCPortMin == 0 {
|
||||
b.config.VNCPortMin = 5900
|
||||
}
|
||||
|
|
|
@ -132,6 +132,25 @@ func TestBuilderPrepare_BootWait(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_VNCBindAddress(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
// Test a default boot_wait
|
||||
delete(config, "vnc_bind_address")
|
||||
warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if b.config.VNCBindAddress != "127.0.0.1" {
|
||||
t.Fatalf("bad value: %s", b.config.VNCBindAddress)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_DiskCompaction(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
|
|
@ -26,7 +26,7 @@ func (stepConfigureVNC) Run(state multistep.StateBag) multistep.StepAction {
|
|||
// Find an open VNC port. Note that this can still fail later on
|
||||
// because we have to release the port at some point. But this does its
|
||||
// best.
|
||||
msg := fmt.Sprintf("Looking for available port between %d and %d", config.VNCPortMin, config.VNCPortMax)
|
||||
msg := fmt.Sprintf("Looking for available port between %d and %d on %s", config.VNCPortMin, config.VNCPortMax, config.VNCBindAddress)
|
||||
ui.Say(msg)
|
||||
log.Printf(msg)
|
||||
var vncPort uint
|
||||
|
@ -39,15 +39,16 @@ func (stepConfigureVNC) Run(state multistep.StateBag) multistep.StepAction {
|
|||
}
|
||||
|
||||
log.Printf("Trying port: %d", vncPort)
|
||||
l, err := net.Listen("tcp", fmt.Sprintf(":%d", vncPort))
|
||||
l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", config.VNCBindAddress, vncPort))
|
||||
if err == nil {
|
||||
defer l.Close()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
ui.Say(fmt.Sprintf("Found available VNC port: %d", vncPort))
|
||||
log.Printf("Found available VNC port: %d on IP: %s", vncPort, config.VNCBindAddress)
|
||||
state.Put("vnc_port", vncPort)
|
||||
state.Put("vnc_ip", config.VNCBindAddress)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
|
|
@ -61,12 +61,13 @@ func (s *stepRun) Cleanup(state multistep.StateBag) {
|
|||
func getCommandArgs(bootDrive string, state multistep.StateBag) ([]string, error) {
|
||||
config := state.Get("config").(*Config)
|
||||
isoPath := state.Get("iso_path").(string)
|
||||
vncIP := state.Get("vnc_ip").(string)
|
||||
vncPort := state.Get("vnc_port").(uint)
|
||||
sshHostPort := state.Get("sshHostPort").(uint)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
driver := state.Get("driver").(Driver)
|
||||
|
||||
vnc := fmt.Sprintf("0.0.0.0:%d", vncPort-5900)
|
||||
vnc := fmt.Sprintf("%s:%d", vncIP, vncPort-5900)
|
||||
vmName := config.VMName
|
||||
imgPath := filepath.Join(config.OutputDir, vmName)
|
||||
|
||||
|
@ -100,9 +101,22 @@ func getCommandArgs(bootDrive string, state multistep.StateBag) ([]string, error
|
|||
deviceArgs = append(deviceArgs, fmt.Sprintf("%s,netdev=user.0", config.NetDevice))
|
||||
|
||||
if config.Headless == true {
|
||||
ui.Message("WARNING: The VM will be started in headless mode, as configured.\n" +
|
||||
"In headless mode, errors during the boot sequence or OS setup\n" +
|
||||
"won't be easily visible. Use at your own discretion.")
|
||||
vncIpRaw, vncIpOk := state.GetOk("vnc_ip")
|
||||
vncPortRaw, vncPortOk := state.GetOk("vnc_port")
|
||||
|
||||
if vncIpOk && vncPortOk {
|
||||
vncIp := vncIpRaw.(string)
|
||||
vncPort := vncPortRaw.(uint)
|
||||
|
||||
ui.Message(fmt.Sprintf(
|
||||
"The VM will be run headless, without a GUI. If you want to\n"+
|
||||
"view the screen of the VM, connect via VNC without a password to\n"+
|
||||
"%s:%d", vncIp, vncPort))
|
||||
} else {
|
||||
ui.Message("The VM will be run headless, without a GUI, as configured.\n" +
|
||||
"If the run isn't succeeding as you expect, please enable the GUI\n" +
|
||||
"to inspect the progress of the build.")
|
||||
}
|
||||
} else {
|
||||
if qemuMajor >= 2 {
|
||||
defaultArgs["-display"] = "sdl"
|
||||
|
|
|
@ -306,6 +306,10 @@ default port of `5985` or whatever value you have the service set to listen on.
|
|||
`BUILDNAME` is the name of the build. Currently, no file extension will be
|
||||
used unless it is specified in this option.
|
||||
|
||||
- `vnc_bind_address` (string / IP address) - The IP address that should be binded
|
||||
to for VNC. By default packer will use 127.0.0.1 for this. If you wish to bind
|
||||
to all interfaces use 0.0.0.0
|
||||
|
||||
- `vnc_port_min` and `vnc_port_max` (integer) - The minimum and maximum port
|
||||
to use for VNC access to the virtual machine. The builder uses VNC to type
|
||||
the initial `boot_command`. Because Packer generally runs in parallel,
|
||||
|
|
Loading…
Reference in New Issue