diff --git a/builder/qemu/config.go b/builder/qemu/config.go index 605f101e9..29b0c71ff 100644 --- a/builder/qemu/config.go +++ b/builder/qemu/config.go @@ -374,6 +374,8 @@ type Config struct { // the initial boot_command. Because Packer generally runs in parallel, // Packer uses a randomly chosen port in this range that appears available. By // default this is 5900 to 6000. The minimum and maximum ports are inclusive. + // The minimum port cannot be set below 5900 due to a quirk in how QEMU parses + // vnc display address. VNCPortMin int `mapstructure:"vnc_port_min" required:"false"` VNCPortMax int `mapstructure:"vnc_port_max"` // This is the name of the image (QCOW2 or IMG) file for @@ -592,6 +594,16 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { } } + if c.VNCPortMin < 5900 { + errs = packersdk.MultiErrorAppend( + errs, fmt.Errorf("vnc_port_min cannot be below 5900")) + } + + if c.VNCPortMin > 65535 || c.VNCPortMax > 65535 { + errs = packersdk.MultiErrorAppend( + errs, fmt.Errorf("vmc_port_min and vnc_port_max must both be below 65535 to be valid TCP ports")) + } + if c.VNCPortMin > c.VNCPortMax { errs = packersdk.MultiErrorAppend( errs, fmt.Errorf("vnc_port_min must be less than vnc_port_max")) diff --git a/builder/qemu/step_run.go b/builder/qemu/step_run.go index 4932eaace..5360955f4 100644 --- a/builder/qemu/step_run.go +++ b/builder/qemu/step_run.go @@ -120,17 +120,18 @@ func (s *stepRun) getDefaultArgs(config *Config, state multistep.StateBag) map[s vncPort := state.Get("vnc_port").(int) vncIP := config.VNCBindAddress - vncPort = vncPort - config.VNCPortMin - vnc := fmt.Sprintf("%s:%d", vncIP, vncPort) + vncRealAddress := fmt.Sprintf("%s:%d", vncIP, vncPort) + vncPort = vncPort - 5900 + vncArgs := fmt.Sprintf("%s:%d", vncIP, vncPort) if config.VNCUsePassword { - vnc = fmt.Sprintf("%s:%d,password", vncIP, vncPort) + vncArgs = fmt.Sprintf("%s:%d,password", vncIP, vncPort) } - defaultArgs["-vnc"] = vnc + defaultArgs["-vnc"] = vncArgs // Track the connection for the user vncPass, _ := state.Get("vnc_password").(string) - message = getVncConnectionMessage(config.Headless, vnc, vncPass) + message = getVncConnectionMessage(config.Headless, vncRealAddress, vncPass) if message != "" { s.ui.Message(message) } diff --git a/builder/qemu/step_run_test.go b/builder/qemu/step_run_test.go index e74f8b312..533b5317a 100644 --- a/builder/qemu/step_run_test.go +++ b/builder/qemu/step_run_test.go @@ -105,7 +105,7 @@ func Test_UserOverrides(t *testing.T) { "-fda", "fake_floppy_path", "-name", "myvm", "-netdev", "user,id=user.0,hostfwd=tcp::5000-:0", - "-vnc", ":5905", + "-vnc", ":5", "-machine", "type=,accel="}, tc.Expected...) @@ -416,7 +416,7 @@ func Test_DriveAndDeviceArgs(t *testing.T) { "-fda", "fake_floppy_path", "-name", "", "-netdev", "user,id=user.0,hostfwd=tcp::5000-:0", - "-vnc", ":5905", + "-vnc", ":5", "-machine", "type=,accel=", "-device", ",netdev=user.0"}, tc.Expected...) @@ -453,7 +453,7 @@ func Test_OptionalConfigOptionsGetSet(t *testing.T) { "-fda", "fake_floppy_path", "-name", "MyFancyName", "-netdev", "user,id=user.0,hostfwd=tcp::5000-:0", - "-vnc", ":5905,password", + "-vnc", ":5,password", "-machine", "type=pc,accel=hvf", "-device", ",netdev=user.0", "-drive", "file=/path/to/test.iso,index=0,media=cdrom", @@ -596,7 +596,7 @@ func Test_Defaults(t *testing.T) { "vnc_port": 5959, }, &stepRun{ui: packersdk.TestUi(t)}, - []string{"-vnc", "1.1.1.1:5959"}, + []string{"-vnc", "1.1.1.1:59"}, "no VNC password should be set", }, { @@ -608,7 +608,7 @@ func Test_Defaults(t *testing.T) { "vnc_port": 5959, }, &stepRun{ui: packersdk.TestUi(t)}, - []string{"-vnc", "1.1.1.1:5959,password"}, + []string{"-vnc", "1.1.1.1:59,password"}, "VNC password should be set", }, { diff --git a/website/content/partials/builder/qemu/Config-not-required.mdx b/website/content/partials/builder/qemu/Config-not-required.mdx index a5fced8ca..dcd274282 100644 --- a/website/content/partials/builder/qemu/Config-not-required.mdx +++ b/website/content/partials/builder/qemu/Config-not-required.mdx @@ -301,6 +301,8 @@ the initial boot_command. Because Packer generally runs in parallel, Packer uses a randomly chosen port in this range that appears available. By default this is 5900 to 6000. The minimum and maximum ports are inclusive. + The minimum port cannot be set below 5900 due to a quirk in how QEMU parses + vnc display address. - `vnc_port_max` (int) - VNC Port Max