Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
private static final String KVMCLOCK = "kvmclock";
private static final String HYPERVCLOCK = "hypervclock";
private static final String WINDOWS = "Windows";
private static final String X86_DEFAULT_VIDEO_MODEL = "vga";
private static final int X86_DEFAULT_VIDEO_RAM_KIB = 32768;
private static final String Q35 = "q35";
private static final String PTY = "pty";
private static final String VNC = "vnc";
Expand Down Expand Up @@ -3330,6 +3332,14 @@ protected VideoDef createVideoDef(VirtualMachineTO vmTO) {
videoRam = NumbersUtil.parseInt(value, videoRam);
}
}
if (StringUtils.isBlank(videoHw) && isGuestX86(vmTO)) {
// With no <video> element libvirt defaults x86 guests to cirrus, which is deprecated
// in QEMU and renders a blank console on recent Windows guests (e.g. Windows Server 2025 Core)
videoHw = X86_DEFAULT_VIDEO_MODEL;
if (videoRam == 0) {
videoRam = X86_DEFAULT_VIDEO_RAM_KIB;
}
}
return new VideoDef(videoHw, videoRam);
}

Expand Down Expand Up @@ -3482,6 +3492,11 @@ public boolean isGuestAarch64() {
return AARCH64.equals(guestCpuArch);
}

protected boolean isGuestX86(VirtualMachineTO vmTO) {
String arch = guestCpuArch != null ? guestCpuArch : vmTO.getArch();
return arch == null || arch.equals("x86_64") || arch.equals("i686");
}

private boolean isGuestS390x() {
return S390X.equals(guestCpuArch);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,63 @@ public void testCreateVideoDef() {
assertXpath(domainDoc, "/video/model/@vram", "200");
}

@Test
public void testCreateVideoDefX86DefaultsToVga() {
VirtualMachineTO to = createDefaultVM(false);

VideoDef videoDef = libvirtComputingResourceSpy.createVideoDef(to);
Document domainDoc = parse(videoDef.toString());
assertXpath(domainDoc, "/video/model/@type", "vga");
assertXpath(domainDoc, "/video/model/@vram", "32768");
}

@Test
public void testCreateVideoDefWindowsDefaultsToVga() {
VirtualMachineTO to = createDefaultVM(false);
to.setOs("Windows Server 2025 (64-bit)");

VideoDef videoDef = libvirtComputingResourceSpy.createVideoDef(to);
Document domainDoc = parse(videoDef.toString());
assertXpath(domainDoc, "/video/model/@type", "vga");
assertXpath(domainDoc, "/video/model/@vram", "32768");
}

@Test
public void testCreateVideoDefExplicitDetailWins() {
VirtualMachineTO to = createDefaultVM(false);
Map<String, String> details = new HashMap<>();
details.put(VmDetailConstants.VIDEO_HARDWARE, "virtio");
details.put(VmDetailConstants.VIDEO_RAM, "65536");
to.setDetails(details);

VideoDef videoDef = libvirtComputingResourceSpy.createVideoDef(to);
Document domainDoc = parse(videoDef.toString());
assertXpath(domainDoc, "/video/model/@type", "virtio");
assertXpath(domainDoc, "/video/model/@vram", "65536");
}

@Test
public void testCreateVideoDefAgentPropertyWins() {
VirtualMachineTO to = createDefaultVM(false);
libvirtComputingResourceSpy.videoHw = "qxl";
libvirtComputingResourceSpy.videoRam = 65536;

VideoDef videoDef = libvirtComputingResourceSpy.createVideoDef(to);
Document domainDoc = parse(videoDef.toString());
assertXpath(domainDoc, "/video/model/@type", "qxl");
assertXpath(domainDoc, "/video/model/@vram", "65536");
}

@Test
public void testCreateVideoDefAarch64UnconfiguredStaysEmpty() {
VirtualMachineTO to = createDefaultVM(false);
to.setArch("aarch64");
libvirtComputingResourceSpy.guestCpuArch = "aarch64";

VideoDef videoDef = libvirtComputingResourceSpy.createVideoDef(to);
assertEquals("", videoDef.toString());
}

@Test
public void testCreateRngDef() {
VirtualMachineTO to = createDefaultVM(false);
Expand Down
Loading