Skip to content

Commit f7e58de

Browse files
Merge pull request #193 from hashicorp/custom_vnc_password
custom VNC password changes
1 parent 5086794 commit f7e58de

File tree

6 files changed

+77
-6
lines changed

6 files changed

+77
-6
lines changed

.web-docs/components/builder/qemu/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,8 @@ necessary for this build to succeed and can be found further down the page.
435435
automatically enables the QMP socket. See `qmp_socket_path`. Defaults to
436436
`false`.
437437

438+
- `vnc_password` (string) - The password to set when VNCUsePassword == true.
439+
438440
- `vnc_port_min` (int) - The minimum and maximum port
439441
to use for VNC access to the virtual machine. The builder uses VNC to type
440442
the initial boot_command. Because Packer generally runs in parallel,

builder/qemu/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,8 @@ type Config struct {
566566
// automatically enables the QMP socket. See `qmp_socket_path`. Defaults to
567567
// `false`.
568568
VNCUsePassword bool `mapstructure:"vnc_use_password" required:"false"`
569+
// The password to set when VNCUsePassword == true.
570+
VNCPassword string `mapstructure:"vnc_password" required:"false"`
569571
// The minimum and maximum port
570572
// to use for VNC access to the virtual machine. The builder uses VNC to type
571573
// the initial boot_command. Because Packer generally runs in parallel,

builder/qemu/config.hcl2spec.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

builder/qemu/config_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/hashicorp/packer-plugin-sdk/common"
1616
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
1717
"github.com/stretchr/testify/assert"
18+
"github.com/stretchr/testify/require"
1819
)
1920

2021
var testPem = `
@@ -714,3 +715,51 @@ func TestBuilderPrepare_cd_content(t *testing.T) {
714715
t.Fatal("cd_content empty")
715716
}
716717
}
718+
719+
func TestVNCPasswordEmptyWhenUsePasswordFalse(t *testing.T) {
720+
var c Config
721+
config := testConfig()
722+
config["vnc_use_password"] = false
723+
config["vnc_password"] = "supersecret"
724+
warns, err := c.Prepare(config)
725+
require.NoError(t, err)
726+
assert.Len(t, warns, 0, "bad: %#v", warns)
727+
pass, _ := VNCPassword(&c)
728+
assert.Empty(t, pass)
729+
}
730+
731+
func TestVNCPasswordRandomWhenVNCPasswordEmpty(t *testing.T) {
732+
var c Config
733+
config := testConfig()
734+
config["vnc_use_password"] = true
735+
config["vnc_password"] = ""
736+
warns, err := c.Prepare(config)
737+
require.NoError(t, err)
738+
assert.Len(t, warns, 0, "bad: %#v", warns)
739+
pass, _ := VNCPassword(&c)
740+
assert.Len(t, pass, 8)
741+
}
742+
743+
func TestVNCPasswordSetWhenVNCPasswordNotEmpty(t *testing.T) {
744+
var c Config
745+
config := testConfig()
746+
config["vnc_use_password"] = true
747+
config["vnc_password"] = "secret"
748+
warns, err := c.Prepare(config)
749+
require.NoError(t, err)
750+
assert.Len(t, warns, 0, "bad: %#v", warns)
751+
pass, _ := VNCPassword(&c)
752+
assert.Equal(t, pass, config["vnc_password"])
753+
}
754+
755+
func TestVNCPasswordErrorWhenPasswordLenMoreThan8(t *testing.T) {
756+
var c Config
757+
config := testConfig()
758+
config["vnc_use_password"] = true
759+
config["vnc_password"] = "secretpassword"
760+
warns, err := c.Prepare(config)
761+
require.NoError(t, err)
762+
assert.Len(t, warns, 0, "bad: %#v", warns)
763+
_, err = VNCPassword(&c)
764+
assert.Error(t, err)
765+
}

builder/qemu/step_configure_vnc.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,19 @@ type stepConfigureVNC struct {
2828
l *net.Listener
2929
}
3030

31-
func VNCPassword() string {
31+
func VNCPassword(c *Config) (string, error) {
32+
if !c.VNCUsePassword {
33+
return "", nil
34+
}
35+
36+
if len(c.VNCPassword) > 8 {
37+
return "", fmt.Errorf("password length is longer than expected %d > %d", len(c.VNCPassword), 8)
38+
}
39+
40+
if len(c.VNCPassword) != 0 {
41+
return c.VNCPassword, nil
42+
}
43+
3244
length := int(8)
3345

3446
charSet := []byte("012345689abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
@@ -40,7 +52,7 @@ func VNCPassword() string {
4052
password[i] = charSet[rand.Intn(charSetLength)]
4153
}
4254

43-
return string(password)
55+
return string(password), nil
4456
}
4557

4658
func (s *stepConfigureVNC) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
@@ -71,10 +83,12 @@ func (s *stepConfigureVNC) Run(ctx context.Context, state multistep.StateBag) mu
7183
s.l.Listener.Close() // free port, but don't unlock lock file
7284
vncPort := s.l.Port
7385

74-
if config.VNCUsePassword {
75-
vncPassword = VNCPassword()
76-
} else {
77-
vncPassword = ""
86+
vncPassword, err = VNCPassword(config)
87+
if err != nil {
88+
err := fmt.Errorf("Error finding VNC password: %s", err)
89+
state.Put("error", err)
90+
ui.Error(err.Error())
91+
return multistep.ActionHalt
7892
}
7993

8094
log.Printf("Found available VNC port: %d on IP: %s", vncPort, config.VNCBindAddress)

docs-partials/builder/qemu/Config-not-required.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,8 @@
335335
automatically enables the QMP socket. See `qmp_socket_path`. Defaults to
336336
`false`.
337337
338+
- `vnc_password` (string) - The password to set when VNCUsePassword == true.
339+
338340
- `vnc_port_min` (int) - The minimum and maximum port
339341
to use for VNC access to the virtual machine. The builder uses VNC to type
340342
the initial boot_command. Because Packer generally runs in parallel,

0 commit comments

Comments
 (0)