Skip to content
Draft
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
17 changes: 17 additions & 0 deletions server/src/main/java/org/apache/cloudstack/ca/CAManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ private boolean provisionKvmHostViaSsh(Host host, String caProvider) {
provisionCertificateViaSsh(sshConnection, hostIp, host.getName(), caProvider);

String sudoPrefix = "root".equals(username) ? "" : "sudo ";
reloadVncTlsCertificateOnRunningVmsViaSsh(sshConnection, sudoPrefix, hostIp);
SSHCmdHelper.sshExecuteCmd(sshConnection, sudoPrefix + "systemctl restart libvirtd");
SSHCmdHelper.sshExecuteCmd(sshConnection, sudoPrefix + "systemctl restart cloudstack-agent");

Expand All @@ -339,6 +340,22 @@ private boolean provisionKvmHostViaSsh(Host host, String caProvider) {
}
}

/**
* Live-reloads the VNC TLS certificate on every running VM via SSH, since a libvirtd/cloudstack-agent restart
* alone does not affect VMs already running. Per-VM failures are tolerated and logged, not thrown.
*/
private void reloadVncTlsCertificateOnRunningVmsViaSsh(final Connection sshConnection, final String sudoPrefix, final String hostIp) {
final String cmd = sudoPrefix + "virsh -c qemu:///system list --name --state-running | while read -r vm; do " +
"[ -z \"$vm\" ] && continue; " +
sudoPrefix + "virsh -c qemu:///system qemu-monitor-command \"$vm\" " +
"'{\"execute\":\"display-reload\",\"arguments\":{\"type\":\"vnc\",\"tls-certs\":true}}' >/dev/null 2>&1 " +
"|| echo \"failed to reload VNC TLS certificate for VM $vm\" >&2; done";
final SSHCmdHelper.SSHCmdResult result = SSHCmdHelper.sshExecuteCmdWithResult(sshConnection, cmd);
if (!result.isSuccess()) {
logger.warn("Failed to reload VNC TLS certificate on running VMs via SSH on host: {}, error: {}", hostIp, result.getStdErr());
}
}

private boolean provisionSystemVmViaSsh(Host host, Boolean reconnect, String caProvider) {
VMInstanceVO vm = vmInstanceDao.findVMByInstanceName(host.getName());
if (vm == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,10 @@ public void testProvisionKvmHostViaSsh() throws Exception {
MockedStatic<SSHCmdHelper> sshCmdHelperMock = Mockito.mockStatic(SSHCmdHelper.class)) {
sshCmdHelperMock.when(() -> SSHCmdHelper.acquireAuthorizedConnectionWithPublicKey(Mockito.any(Connection.class), Mockito.anyString(), Mockito.anyString()))
.thenReturn(true);
sshCmdHelperMock.when(() -> SSHCmdHelper.sshExecuteCmdWithResult(Mockito.any(Connection.class), Mockito.contains("virsh")))
.thenReturn(new SSHCmdHelper.SSHCmdResult(0, "", ""));
sshCmdHelperMock.when(() -> SSHCmdHelper.sshExecuteCmd(Mockito.any(Connection.class), Mockito.anyString()))
.thenReturn(true);

Mockito.doNothing().when(caManager).provisionCertificateViaSsh(Mockito.any(Connection.class), Mockito.anyString(), Mockito.anyString(), Mockito.anyString());

Expand All @@ -290,8 +294,9 @@ public void testProvisionKvmHostViaSsh() throws Exception {

Assert.assertTrue(result);
Mockito.verify(caManager, Mockito.times(1)).provisionCertificateViaSsh(Mockito.any(Connection.class), Mockito.eq("192.168.1.1"), Mockito.eq("host1"), Mockito.eq("root"));
sshCmdHelperMock.verify(() -> SSHCmdHelper.sshExecuteCmd(Mockito.any(Connection.class), Mockito.eq("systemctl restart libvirtd")), Mockito.times(1));
sshCmdHelperMock.verify(() -> SSHCmdHelper.sshExecuteCmd(Mockito.any(Connection.class), Mockito.eq("systemctl restart cloudstack-agent")), Mockito.times(1));
sshCmdHelperMock.verify(() -> SSHCmdHelper.sshExecuteCmdWithResult(Mockito.any(Connection.class), Mockito.contains("virsh")), Mockito.times(1));
sshCmdHelperMock.verify(() -> SSHCmdHelper.sshExecuteCmd(Mockito.any(Connection.class), Mockito.contains("systemctl restart libvirtd")), Mockito.times(1));
sshCmdHelperMock.verify(() -> SSHCmdHelper.sshExecuteCmd(Mockito.any(Connection.class), Mockito.contains("systemctl restart cloudstack-agent")), Mockito.times(1));
}
}

Expand Down
Loading