Skip to content

Commit 13a5e78

Browse files
committed
Add VNC video display including websockets
The other display options open a window always, while the vnc is more "on demand" by using a separate vnc viewer. Add localhost and password support for some minimal security, and websocket support for running novnc in a web browser. Signed-off-by: Anders F Björklund <[email protected]>
1 parent 16fdf29 commit 13a5e78

File tree

5 files changed

+67
-3
lines changed

5 files changed

+67
-3
lines changed

examples/default.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,18 @@ video:
215215
# on performance on macOS hosts: https://gitlab.com/qemu-project/qemu/-/issues/334
216216
# 🟢 Builtin default: "none"
217217
display: null
218+
# VNC (Virtual Network Computing) is a platform-independent graphical
219+
# desktop-sharing system that uses the Remote Frame Buffer protocol (RFB)
220+
vnc:
221+
# VNC display, e.g., "127.0.0.1:0", "host:d", "unix:path", "none"
222+
# By convention the TCP port is 5900+d, connections from any host.
223+
display: null
224+
# VNC websocket, e.g. "127.0.0.1:5700", "host:port"
225+
# By convention the TCP port is 5700+d, connections from any host.
226+
websocket: null
227+
# VNC password, e.g. "on", "off"
228+
# Use QMP to set password: `change-vnc-password password=secret`
229+
password: null
218230

219231
# The instance can get routable IP addresses from the vmnet framework using
220232
# https://github.com/lima-vm/vde_vmnet.

pkg/limayaml/defaults.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,25 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
169169
y.Video.Display = pointer.String("none")
170170
}
171171

172+
if y.Video.VNC.Display == nil {
173+
y.Video.VNC.Display = d.Video.VNC.Display
174+
}
175+
if o.Video.VNC.Display != nil {
176+
y.Video.VNC.Display = o.Video.VNC.Display
177+
}
178+
if y.Video.VNC.WebSocket == nil {
179+
y.Video.VNC.WebSocket = d.Video.VNC.WebSocket
180+
}
181+
if o.Video.VNC.WebSocket != nil {
182+
y.Video.VNC.WebSocket = o.Video.VNC.WebSocket
183+
}
184+
if y.Video.VNC.Password == nil {
185+
y.Video.VNC.Password = d.Video.VNC.Password
186+
}
187+
if o.Video.VNC.Password != nil {
188+
y.Video.VNC.Password = o.Video.VNC.Password
189+
}
190+
172191
if y.Firmware.LegacyBIOS == nil {
173192
y.Firmware.LegacyBIOS = d.Firmware.LegacyBIOS
174193
}

pkg/limayaml/limayaml.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,16 @@ type Firmware struct {
106106
LegacyBIOS *bool `yaml:"legacyBIOS,omitempty" json:"legacyBIOS,omitempty"`
107107
}
108108

109+
type VNCOptions struct {
110+
Display *string `yaml:"display,omitempty" json:"display,omitempty"`
111+
WebSocket *string `yaml:"websocket,omitempty" json:"websocket,omitempty"`
112+
Password *string `yaml:"password,omitempty" json:"password,omitempty"`
113+
}
114+
109115
type Video struct {
110116
// Display is a QEMU display string
111-
Display *string `yaml:"display,omitempty" json:"display,omitempty"`
117+
Display *string `yaml:"display,omitempty" json:"display,omitempty"`
118+
VNC VNCOptions `yaml:"vnc" json:"vnc"`
112119
}
113120

114121
type ProvisionMode = string

pkg/limayaml/validate.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,22 @@ func Validate(y LimaYAML, warn bool) error {
8888
}
8989
}
9090

91+
if y.Video.VNC.Display != nil {
92+
if *y.Video.Display != "none" && *y.Video.Display != "vnc" {
93+
return fmt.Errorf("field `video.display` has conflicting type: %q", *y.Video.Display)
94+
}
95+
}
96+
if y.Video.VNC.WebSocket != nil {
97+
if y.Video.VNC.Display == nil || *y.Video.VNC.Display == "" {
98+
return errors.New("field `video.vnc.display` must be set before video.vnc.websocket")
99+
}
100+
}
101+
if y.Video.VNC.Password != nil {
102+
if y.Video.VNC.Display == nil || *y.Video.VNC.Display == "" {
103+
return errors.New("field `video.vnc.display` must be set before video.vnc.password")
104+
}
105+
}
106+
91107
if *y.CPUs == 0 {
92108
return errors.New("field `cpus` must be set")
93109
}

pkg/qemu/qemu.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,8 +509,18 @@ func Cmdline(cfg Config) (string, []string, error) {
509509
args = append(args, "-device", "virtio-rng-pci")
510510

511511
// Graphics
512-
if *y.Video.Display != "" {
513-
args = appendArgsIfNoConflict(args, "-display", *y.Video.Display)
512+
if *y.Video.Display != "" || y.Video.VNC.Display != nil {
513+
display := *y.Video.Display
514+
if y.Video.VNC.Display != nil {
515+
display = "vnc=" + *y.Video.VNC.Display
516+
}
517+
if y.Video.VNC.WebSocket != nil {
518+
display += ",websocket=" + *y.Video.VNC.WebSocket
519+
}
520+
if y.Video.VNC.Password != nil {
521+
display += ",password=" + *y.Video.VNC.Password
522+
}
523+
args = appendArgsIfNoConflict(args, "-display", display)
514524
}
515525
switch *y.Arch {
516526
case limayaml.X8664:

0 commit comments

Comments
 (0)