This is an automated email from the ASF dual-hosted git repository.

pearl11594 pushed a commit to branch test-opt
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit 239ee80a888756c988c2ea45295273a397e9e0a2
Author: Pearl Dsilva <[email protected]>
AuthorDate: Tue Dec 14 18:25:07 2021 +0530

    - Support to patch SystemVMs - VMWare
    - Remove attaching systemvm.iso to systemVMs
    - Modify / Refactor VMware start command to copy patch related files to the 
systemvms
    - cleanup
---
 .../hypervisor/vmware/resource/VmwareResource.java | 114 ++++++++++++++++++++-
 .../xenbase/CitrixPatchSystemVmCommandWrapper.java |  19 ++--
 scripts/vm/hypervisor/xenserver/vmops              |  16 ++-
 .../main/java/com/cloud/vm/UserVmManagerImpl.java  |   2 +-
 4 files changed, 136 insertions(+), 15 deletions(-)

diff --git 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index ed37391..669ae08 100644
--- 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -48,6 +48,10 @@ import java.util.stream.Collectors;
 import javax.naming.ConfigurationException;
 import javax.xml.datatype.XMLGregorianCalendar;
 
+import com.cloud.agent.api.PatchSystemVmAnswer;
+import com.cloud.agent.api.PatchSystemVmCommand;
+import com.cloud.resource.ServerResourceBase;
+import com.cloud.utils.FileUtil;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
@@ -362,9 +366,10 @@ import com.vmware.vim25.VmConfigSpec;
 import com.vmware.vim25.VmwareDistributedVirtualSwitchPvlanSpec;
 import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
 
-public class VmwareResource implements StoragePoolResource, ServerResource, 
VmwareHostService, VirtualRouterDeployer {
+public class VmwareResource extends ServerResourceBase implements 
StoragePoolResource, ServerResource, VmwareHostService, VirtualRouterDeployer {
     private static final Logger s_logger = 
Logger.getLogger(VmwareResource.class);
     public static final String VMDK_EXTENSION = ".vmdk";
+    public static final String BASEPATH = "/usr/share/cloudstack-common/vms/";
 
     private static final Random RANDOM = new Random(System.nanoTime());
 
@@ -594,7 +599,9 @@ public class VmwareResource implements StoragePoolResource, 
ServerResource, Vmwa
                 answer = execute((SetupPersistentNetworkCommand) cmd);
             } else if (clz == GetVmVncTicketCommand.class) {
                 answer = execute((GetVmVncTicketCommand) cmd);
-            } else {
+            } else if (clz == PatchSystemVmCommand.class) {
+            answer = execute((PatchSystemVmCommand) cmd);
+        } else {
                 answer = Answer.createUnsupportedCommandAnswer(cmd);
             }
 
@@ -634,6 +641,68 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
         return answer;
     }
 
+    private ExecutionResult getSystemVmVersionAndChecksum(String controlIp) {
+        ExecutionResult result;
+        try {
+            result = executeInVR(controlIp, VRScripts.VERSION, null);
+            if (!result.isSuccess()) {
+                String errMsg = String.format("GetSystemVMVersionCmd on %s 
failed, message %s", controlIp, result.getDetails());
+                s_logger.error(errMsg);
+                throw new CloudRuntimeException(errMsg);
+            }
+        } catch (final Exception e) {
+            final String msg = "GetSystemVMVersionCmd failed due to " + e;
+            s_logger.error(msg, e);
+            throw new CloudRuntimeException(msg, e);
+        }
+        return result;
+    }
+
+    private Answer execute(PatchSystemVmCommand cmd) {
+        String controlIp = getRouterSshControlIp(cmd);
+        String sysVMName = 
cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        String homeDir = System.getProperty("user.home");
+        File pemFile = new File(homeDir + "/.ssh/id_rsa");
+
+        ExecutionResult result = getSystemVmVersionAndChecksum(controlIp);
+        try {
+            FileUtil.scpPatchFiles(controlIp, "/home/cloud", 
DefaultDomRSshPort, pemFile, newSrcFiles, BASEPATH);
+        } catch (CloudRuntimeException e) {
+            return new PatchSystemVmAnswer(cmd, e.getMessage());
+        }
+
+        final String[] lines = result.getDetails().split("&");
+        // TODO: do we fail, or patch anyway??
+        if (lines.length != 2) {
+            return new PatchSystemVmAnswer(cmd, result.getDetails());
+        }
+
+        String scriptChecksum = lines[1].trim();
+        String checksum = calculateCurrentChecksum(sysVMName).trim();
+
+        if (!org.apache.commons.lang3.StringUtils.isEmpty(checksum) && 
checksum.equals(scriptChecksum)) {
+            if (!cmd.isForced()) {
+                String msg = String.format("No change in the scripts checksum, 
not patching systemVM %s", sysVMName);
+                s_logger.info(msg);
+                return new PatchSystemVmAnswer(cmd, msg, lines[0], lines[1]);
+            }
+        }
+
+        Pair<Boolean, String> patchResult = null;
+        try {
+            patchResult = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, 
"root",
+                    pemFile, null, "/home/cloud/patch-sysvms.sh", 10000, 
10000, 60000);
+        } catch (Exception e) {
+            return new PatchSystemVmAnswer(cmd, e.getMessage());
+        }
+
+        if (patchResult.first()) {
+            return new PatchSystemVmAnswer(cmd, String.format("Successfully 
patched systemVM %s ", sysVMName), lines[0], lines[1]);
+        }
+        return new PatchSystemVmAnswer(cmd, patchResult.second());
+
+    }
+
     private Answer execute(SetupPersistentNetworkCommand cmd) {
         VmwareHypervisorHost host = getHyperHost(getServiceContext());
         String hostname = null;
@@ -2100,7 +2169,7 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
 
                 deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
                 Pair<VirtualDevice, Boolean> isoInfo = 
VmwareHelper.prepareIsoDevice(vmMo,
-                        String.format("[%s] systemvm/%s", secDsMo.getName(), 
mgr.getSystemVMIsoFileNameOnDatastore()), secDsMo.getMor(), true, true, 
ideUnitNumber++, i + 1);
+                        null, secDsMo.getMor(), true, true, ideUnitNumber++, i 
+ 1);
                 deviceConfigSpecArray[i].setDevice(isoInfo.first());
                 if (isoInfo.second()) {
                     if (s_logger.isDebugEnabled())
@@ -2485,6 +2554,29 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
 
             startAnswer.setIqnToData(iqnToData);
 
+            if (vmSpec.getType() != VirtualMachine.Type.User) {
+                String controlIp = getControlIp(nics);
+                // check if the router is up?
+                for (int count = 0; count < 60; count++) {
+                    final boolean result = _vrResource.connect(controlIp, 1, 
5000);
+                    if (result) {
+                        break;
+                    }
+                }
+
+                try {
+                    String homeDir = System.getProperty("user.home");
+                    File pemFile = new File(homeDir + "/.ssh/id_rsa");
+                    FileUtil.scpPatchFiles(controlIp, "/home/cloud", 
DefaultDomRSshPort, pemFile, newSrcFiles, BASEPATH);
+                    // TODO: May want to remove this when cert patching logic 
is moved
+                    Thread.sleep(10000);
+                } catch (Exception e) {
+                    String errMsg = "Failed to scp files to system VM. 
Patching of systemVM failed";
+                    s_logger.error(errMsg, e);
+                    return new StartAnswer(cmd, String.format("%s due to: %s", 
errMsg, e.getMessage()));
+                }
+            }
+
             // Since VM was successfully powered-on, if there was an existing 
VM in a different cluster that was unregistered, delete all the files 
associated with it.
             if (existingVmName != null && existingVmFileLayout != null) {
                 List<String> vmDatastoreNames = new ArrayList<String>();
@@ -3886,6 +3978,17 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
         }
     }
 
+    private String getControlIp(NicTO[] nicTOs) {
+        String controlIpAddress = null;
+        for (NicTO nic : nicTOs) {
+            if ((TrafficType.Management == nic.getType() || 
TrafficType.Control == nic.getType()) && nic.getIp() != null) {
+                controlIpAddress = nic.getIp();
+                break;
+            }
+        }
+        return controlIpAddress;
+    }
+
     private VirtualMachineMO takeVmFromOtherHyperHost(VmwareHypervisorHost 
hyperHost, String vmName) throws Exception {
 
         VirtualMachineMO vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
@@ -6974,6 +7077,11 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
     }
 
     @Override
+    protected String getDefaultScriptsDir() {
+        return null;
+    }
+
+    @Override
     public boolean start() {
         return true;
     }
diff --git 
a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPatchSystemVmCommandWrapper.java
 
b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPatchSystemVmCommandWrapper.java
index e27381e..a6b183f 100644
--- 
a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPatchSystemVmCommandWrapper.java
+++ 
b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPatchSystemVmCommandWrapper.java
@@ -25,10 +25,8 @@ import 
com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
 import com.cloud.resource.CommandWrapper;
 import com.cloud.resource.ResourceWrapper;
 import com.cloud.utils.ExecutionResult;
-import com.cloud.utils.FileUtil;
-import com.cloud.utils.Pair;
 import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.ssh.SshHelper;
+import com.xensource.xenapi.Connection;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
 
@@ -44,12 +42,13 @@ public class CitrixPatchSystemVmCommandWrapper extends 
CommandWrapper<PatchSyste
     public Answer execute(PatchSystemVmCommand command, CitrixResourceBase 
serverResource) {
         final String controlIp = 
command.getAccessDetail(NetworkElementCommand.ROUTER_IP);
         final String sysVMName = 
command.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-
+        final Connection conn = serverResource.getConnection();
 
         ExecutionResult result;
         try {
             result = getSystemVmVersionAndChecksum(serverResource, controlIp);
-            FileUtil.scpPatchFiles(controlIp, "/home/cloud", sshPort, pemFile, 
serverResource.newSrcFiles, CitrixResourceBase.BASEPATH);
+            serverResource.copyPatchFilesToVR(controlIp, "/home/cloud");
+            //FileUtil.scpPatchFiles(controlIp, "/home/cloud", sshPort, 
pemFile, serverResource.newSrcFiles, CitrixResourceBase.BASEPATH);
         } catch (CloudRuntimeException e) {
             return new PatchSystemVmAnswer(command, e.getMessage());
         }
@@ -70,18 +69,18 @@ public class CitrixPatchSystemVmCommandWrapper extends 
CommandWrapper<PatchSyste
                 return new PatchSystemVmAnswer(command, msg, lines[0], 
lines[1]);
             }
         }
-        Pair<Boolean, String> patchResult = null;
+        String patchResult = null;
         try {
-            patchResult = SshHelper.sshExecute(controlIp, sshPort, "root",
-                    pemFile, null, "/home/cloud/patch-sysvms.sh", 10000, 
10000, 60000);
+            patchResult = serverResource.callHostPlugin(conn, "vmops", 
"runPatchScriptInDomr", "domrip", controlIp);
         } catch (Exception e) {
             return new PatchSystemVmAnswer(command, e.getMessage());
         }
 
-        if (patchResult.first()) {
+
+        if (patchResult.startsWith("succ#")) {
             return new PatchSystemVmAnswer(command, 
String.format("Successfully patched systemVM %s ", sysVMName), lines[0], 
lines[1]);
         }
-        return new PatchSystemVmAnswer(command, patchResult.second());
+        return new PatchSystemVmAnswer(command, patchResult.substring(5));
 
     }
 
diff --git a/scripts/vm/hypervisor/xenserver/vmops 
b/scripts/vm/hypervisor/xenserver/vmops
index e5c7e1a..cea47cc 100755
--- a/scripts/vm/hypervisor/xenserver/vmops
+++ b/scripts/vm/hypervisor/xenserver/vmops
@@ -249,6 +249,19 @@ def createFileInDomr(session, args):
     return txt
 
 @echo
+def runPatchScriptInDomr(session, args):
+    domrip = args['domrip']
+    txt=""
+    try:
+        target = "root@" + domrip
+        txt = util.pread2(['ssh','-p','3922','-i','/root/.ssh/id_rsa.cloud', 
target, "/bin/bash","/home/cloud/patch-sysvms.sh"])
+        txt = 'succ#' + txt
+    except:
+        logging.debug("failed to run patch script in systemVM with IP:  " + 
domrip)
+        txt = 'fail#' + txt
+    return txt
+
+@echo
 def deleteFile(session, args):
     file_path = args["filepath"]
 
@@ -1590,4 +1603,5 @@ if __name__ == "__main__":
                             "cleanup_rules":cleanup_rules,
                             "createFileInDomr":createFileInDomr,
                             "kill_copy_process":kill_copy_process,
-                            "secureCopyToHost":secureCopyToHost})
+                            "secureCopyToHost":secureCopyToHost,
+                            "runPatchScriptInDomr": runPatchScriptInDomr})
diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java 
b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
index d7c90b3..a3b7c47 100644
--- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
@@ -4874,7 +4874,7 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
     }
 
     @Override
-    public boolean  finalizeStart(VirtualMachineProfile profile, long hostId, 
Commands cmds, ReservationContext context) {
+    public boolean finalizeStart(VirtualMachineProfile profile, long hostId, 
Commands cmds, ReservationContext context) {
         UserVmVO vm = _vmDao.findById(profile.getId());
 
         Answer[] answersToCmds = cmds.getAnswers();

Reply via email to