Damans227 commented on code in PR #14151:
URL: https://github.com/apache/cloudstack/pull/14151#discussion_r4166214336


##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPostCertificateRenewalCommandWrapper.java:
##########
@@ -29,18 +32,82 @@
 @ResourceWrapper(handles =  PostCertificateRenewalCommand.class)
 public final class LibvirtPostCertificateRenewalCommandWrapper extends 
CommandWrapper<PostCertificateRenewalCommand, Answer, LibvirtComputingResource> 
{
 
+    /**
+     * QMP {@code display-reload} command asking QEMU to reload the VNC 
display's TLS credentials off disk.
+     * {@code tls-certs: true} is required, otherwise QEMU reloads the display 
without touching the certificates.
+     * Added in QEMU 6.0 by commit 9cc07651655ee86eca41059f5ead8c4e5607c734 
("qmp: add new qmp display-reload",
+     * merged 2021-03-23) - 
https://github.com/qemu/qemu/commit/9cc07651655ee86eca41059f5ead8c4e5607c734
+     */
+    private static final String 
QEMU_MONITOR_DISPLAY_RELOAD_VNC_TLS_CERTS_COMMAND =
+            
"{\"execute\":\"display-reload\",\"arguments\":{\"type\":\"vnc\",\"tls-certs\":true}}";
+
+    /** Minimum QEMU version supporting {@link 
#QEMU_MONITOR_DISPLAY_RELOAD_VNC_TLS_CERTS_COMMAND}. */
+    private static final long MIN_QEMU_VERSION_FOR_VNC_TLS_CERT_RELOAD = 
6000000L;
 
     @Override
     public Answer execute(final PostCertificateRenewalCommand command, final 
LibvirtComputingResource serverResource) {
-        logger.info("Restarting libvirt after certificate 
provisioning/renewal");
         if (command != null) {
-            final int timeout = 30000;
-            Script script = new Script(true, "service", timeout, logger);
-            script.add("libvirtd");
-            script.add("restart");
-            script.execute();
+            pushRenewedVncCertificateToRunningVms(serverResource);
+            restartLibvirtd();
             return new SetupCertificateAnswer(true);
        }
         return new SetupCertificateAnswer(false);
     }
+
+    private void restartLibvirtd() {
+        logger.info("Restarting libvirt after certificate 
provisioning/renewal");
+        final int timeout = 30000;
+        Script script = new Script(true, "service", timeout, logger);
+        script.add("libvirtd");
+        script.add("restart");
+        script.execute();
+    }
+
+    /**
+     * The VNC TLS certificate on KVM is the host's agent certificate, applied 
host-wide via libvirtd's
+     * {@code vnc_tls_x509_cert_dir} setting. Restarting libvirtd does not 
affect VMs already running, since QEMU
+     * only loads that certificate once, at VM start - so reload it live on 
every running VM here, instead of
+     * leaving them on the previous (possibly expired) certificate until 
stopped/started or migrated.
+     */
+    private void pushRenewedVncCertificateToRunningVms(final 
LibvirtComputingResource serverResource) {
+        final long qemuVersion = serverResource.getHypervisorQemuVersion();
+        if (qemuVersion < MIN_QEMU_VERSION_FOR_VNC_TLS_CERT_RELOAD) {
+            logger.warn("QEMU {} on this host does not support reloading the 
VNC TLS certificate of a running VM (QEMU >= {} required), " +
+                    "running VMs will keep using the previous certificate 
until they are stopped/started or migrated",
+                    qemuVersion, MIN_QEMU_VERSION_FOR_VNC_TLS_CERT_RELOAD);
+            return;
+        }
+
+        final Connect conn;
+        final int[] domainIds;
+        try {
+            conn = serverResource.getLibvirtUtilitiesHelper().getConnection();
+            domainIds = conn.listDomains();
+        } catch (final LibvirtException e) {
+            logger.warn("Unable to list running VMs to reload their renewed 
VNC certificate", e);
+            return;
+        }
+
+        for (final int domainId : domainIds) {
+            Domain vm = null;
+            String vmName = null;
+            try {
+                vm = conn.domainLookupByID(domainId);
+                vmName = vm.getName();
+                
vm.qemuMonitorCommand(QEMU_MONITOR_DISPLAY_RELOAD_VNC_TLS_CERTS_COMMAND, 0);

Review Comment:
   what happens on hosts where vnc tls is turned off? looks like every running 
vm would log a failure with a stack trace on each renewal



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to