You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ro...@apache.org on 2019/05/23 12:38:08 UTC

[cloudstack] branch 4.11 updated: server: ssh-keygen in PEM format and reduce main systemvm patching script (#3333)

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

rohit pushed a commit to branch 4.11
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.11 by this push:
     new 0929866  server: ssh-keygen in PEM format and reduce main systemvm patching script (#3333)
0929866 is described below

commit 09298669562032c6f112cf8d407009abc42f1135
Author: Rohit Yadav <ro...@shapeblue.com>
AuthorDate: Thu May 23 18:08:00 2019 +0530

    server: ssh-keygen in PEM format and reduce main systemvm patching script (#3333)
    
    On first startup, the management server creates and saves a random
    ssh keypair using ssh-keygen in the database. The command does
    not specify keys in PEM format which is not the default as generated
    by latest ssh-keygen tool.
    
    The systemvmtemplate always needs re-building whenever there is a change
    in the cloud-early-config file. This also tries to fix that by introducing a
    stage 2 bootstrap.sh where the changes specific to hypervisor detection
    etc are refactored/moved. The initial cloud-early-config only patches
    before the other scripts are called.
    
    Signed-off-by: Rohit Yadav <ro...@shapeblue.com>
---
 .travis.yml                                        |  46 ++++---
 .../kvm/resource/LibvirtComputingResource.java     |   2 +-
 .../wrapper/LibvirtStartCommandWrapper.java        |  11 +-
 .../com/cloud/server/ConfigurationServerImpl.java  |  29 ++--
 services/console-proxy-rdp/rdpconsole/pom.xml      |  11 ++
 .../bin/setup/{cloud-early-config => bootstrap.sh} | 114 ++++++----------
 .../debian/opt/cloud/bin/setup/cloud-early-config  | 147 ++-------------------
 .../debian/opt/cloud/bin/setup/patchsystemvm.sh    |  63 ---------
 systemvm/debian/opt/cloud/bin/setup/router.sh      |   4 +-
 systemvm/debian/opt/cloud/bin/setup/vpcrouter.sh   |   6 +-
 .../scripts/install_systemvm_packages.sh           |   1 +
 11 files changed, 115 insertions(+), 319 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 43f2bb2..49bbc33 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -99,28 +99,30 @@ env:
              smoke/test_volumes
              smoke/test_vpc_redundant
              smoke/test_vpc_router_nics
-             smoke/test_vpc_vpn
-             smoke/misc/test_deploy_vm
+             smoke/test_vpc_vpn"
+
+    - TESTS="smoke/misc/test_deploy_vm
              smoke/misc/test_escalations_templates
              smoke/misc/test_vm_ha
-             smoke/misc/test_vm_sync"
-
-    - TESTS="component/find_hosts_for_migration
+             smoke/misc/test_vm_sync
+             component/find_hosts_for_migration
              component/test_acl_isolatednetwork_delete
              component/test_acl_listsnapshot
              component/test_acl_listvm
-             component/test_acl_listvolume
-             component/test_acl_sharednetwork"
-
-    - TESTS="component/test_allocation_states
-             component/test_acl_sharednetwork_deployVM-impersonation
-             component/test_affinity_groups_projects
-             component/test_cpu_domain_limits
-             component/test_cpu_limits"
-
-    - TESTS="component/test_cpu_max_limits
-             component/test_cpu_project_limits
-             component/test_deploy_vm_userdata_multi_nic
+             component/test_acl_listvolume"
+
+    - TESTS="component/test_acl_sharednetwork
+             component/test_acl_sharednetwork_deployVM-impersonation"
+
+    - TESTS="component/test_affinity_groups_projects
+             component/test_allocation_states"
+
+    - TESTS="component/test_cpu_domain_limits
+             component/test_cpu_limits
+             component/test_cpu_max_limits
+             component/test_cpu_project_limits"
+
+    - TESTS="component/test_deploy_vm_userdata_multi_nic
              component/test_egress_fw_rules
              component/test_invalid_gw_nm
              component/test_ip_reservation
@@ -129,16 +131,18 @@ env:
     - TESTS="component/test_memory_limits
              component/test_mm_domain_limits
              component/test_mm_max_limits
-             component/test_mm_project_limits
-             component/test_network_offering
+             component/test_mm_project_limits"
+
+    - TESTS="component/test_network_offering
              component/test_non_contiguous_vlan
              component/test_persistent_networks"
 
     - TESTS="component/test_project_limits
              component/test_project_configs
              component/test_project_usage
-             component/test_project_resources
-             component/test_regions_accounts
+             component/test_project_resources"
+
+    - TESTS="component/test_regions_accounts
              component/test_routers
              component/test_snapshots
              component/test_stopped_vm"
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index f5f38ed..6b4ed39 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -1362,7 +1362,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
     }
 
     public boolean passCmdLine(final String vmName, final String cmdLine) throws InternalErrorException {
-        final Script command = new Script(_patchScriptPath, 30 * 1000, s_logger);
+        final Script command = new Script(_patchScriptPath, 300 * 1000, s_logger);
         String result;
         command.add("-n", vmName);
         command.add("-c", cmdLine);
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java
index 18abb1c..e31401d 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java
@@ -125,9 +125,14 @@ public final class LibvirtStartCommandWrapper extends CommandWrapper<StartComman
                 // try to patch and SSH into the systemvm for up to 5 minutes
                 for (int count = 0; count < 10; count++) {
                     // wait and try passCmdLine for 30 seconds at most for CLOUDSTACK-2823
-                    libvirtComputingResource.passCmdLine(vmName, vmSpec.getBootArgs());
-                    // check router is up?
-                    final VirtualRoutingResource virtRouterResource = libvirtComputingResource.getVirtRouterResource();
+                    if (libvirtComputingResource.passCmdLine(vmName, vmSpec.getBootArgs())) {
+                        break;
+                    }
+                }
+
+                final VirtualRoutingResource virtRouterResource = libvirtComputingResource.getVirtRouterResource();
+                // check if the router is up?
+                for (int count = 0; count < 60; count++) {
                     final boolean result = virtRouterResource.connect(controlIp, 1, 5000);
                     if (result) {
                         break;
diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java
index eb0dc90..df54873 100644
--- a/server/src/com/cloud/server/ConfigurationServerImpl.java
+++ b/server/src/com/cloud/server/ConfigurationServerImpl.java
@@ -16,13 +16,12 @@
 // under the License.
 package com.cloud.server;
 
-import java.io.DataInputStream;
-import java.io.EOFException;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.nio.file.Files;
 import java.security.NoSuchAlgorithmException;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
@@ -608,29 +607,23 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
             // FIXME: take a global database lock here for safety.
             boolean onWindows = isOnWindows();
             if(!onWindows) {
-                Script.runSimpleBashScript("if [ -f " + privkeyfile + " ]; then rm -f " + privkeyfile + "; fi; ssh-keygen -t rsa -N '' -f " + privkeyfile + " -q");
+                Script.runSimpleBashScript("if [ -f " + privkeyfile + " ]; then rm -f " + privkeyfile + "; fi; ssh-keygen -t rsa -m PEM -N '' -f " + privkeyfile + " -q 2>/dev/null || ssh-keygen -t rsa -N '' -f " + privkeyfile + " -q");
             }
 
-            byte[] arr1 = new byte[4094]; // configuration table column value size
-            try (DataInputStream dis = new DataInputStream(new FileInputStream(privkeyfile))) {
-                dis.readFully(arr1);
-            } catch (EOFException e) {
-                s_logger.info("[ignored] eof reached");
-            } catch (Exception e) {
+            final String privateKey;
+            final String publicKey;
+            try {
+                privateKey = new String(Files.readAllBytes(privkeyfile.toPath()));
+            } catch (IOException e) {
                 s_logger.error("Cannot read the private key file", e);
                 throw new CloudRuntimeException("Cannot read the private key file");
             }
-            String privateKey = new String(arr1).trim();
-            byte[] arr2 = new byte[4094]; // configuration table column value size
-            try (DataInputStream dis = new DataInputStream(new FileInputStream(pubkeyfile))) {
-                dis.readFully(arr2);
-            } catch (EOFException e) {
-                s_logger.info("[ignored] eof reached");
-            } catch (Exception e) {
-                s_logger.warn("Cannot read the public key file", e);
+            try {
+                publicKey = new String(Files.readAllBytes(pubkeyfile.toPath()));
+            } catch (IOException e) {
+                s_logger.error("Cannot read the public key file", e);
                 throw new CloudRuntimeException("Cannot read the public key file");
             }
-            String publicKey = new String(arr2).trim();
 
             final String insertSql1 =
                     "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " +
diff --git a/services/console-proxy-rdp/rdpconsole/pom.xml b/services/console-proxy-rdp/rdpconsole/pom.xml
index d8550a0..eaa99c5 100755
--- a/services/console-proxy-rdp/rdpconsole/pom.xml
+++ b/services/console-proxy-rdp/rdpconsole/pom.xml
@@ -52,6 +52,17 @@
         <directory>${basedir}/src/test/resources</directory>
       </testResource>
     </testResources>
+    <plugins>
+        <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+                <excludes>
+                    <exclude>rdpclient/MockServerTest.java</exclude>
+                </excludes>
+            </configuration>
+        </plugin>
+    </plugins>
   </build>
 
   <dependencies>
diff --git a/systemvm/debian/opt/cloud/bin/setup/cloud-early-config b/systemvm/debian/opt/cloud/bin/setup/bootstrap.sh
similarity index 68%
copy from systemvm/debian/opt/cloud/bin/setup/cloud-early-config
copy to systemvm/debian/opt/cloud/bin/setup/bootstrap.sh
index 6aa0314..0208b36 100755
--- a/systemvm/debian/opt/cloud/bin/setup/cloud-early-config
+++ b/systemvm/debian/opt/cloud/bin/setup/bootstrap.sh
@@ -16,17 +16,9 @@
 # specific language governing permissions and limitations
 # under the License.
 
-#set -x
-#exec 3>&0 4>&1 > /var/log/test.log 2>&1
 PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
 CMDLINE=/var/cache/cloud/cmdline
 
-# Clear boot up flag, it would be created by rc.local after boot up done
-mkdir -p /var/cache/cloud
-rm -f /var/cache/cloud/boot_up_done
-
-[ -x /sbin/ifup ] || exit 0
-
 . /lib/lsb/init-functions
 
 log_it() {
@@ -90,11 +82,6 @@ get_boot_params() {
           sed -i "s/%/ /g" $CMDLINE
           ;;
      kvm)
-          # Use any old cmdline as backup only
-          if [ -s $CMDLINE ]; then
-            mv $CMDLINE $CMDLINE.old
-            log_it "Found a non-empty old cmdline file"
-          fi
           systemctl enable --now qemu-guest-agent
           # Wait for $CMDLINE file to be written by the qemu-guest-agent
           for i in {1..60}; do
@@ -104,14 +91,8 @@ get_boot_params() {
             fi
             sleep 1
           done
-          # Use any old cmdline only when new cmdline is not received
-          if [ -e $CMDLINE.old ]; then
-            if [ -s $CMDLINE  ]; then
-              rm $CMDLINE.old
-            else
-              mv $CMDLINE.old $CMDLINE
-              log_it "Using old cmdline file, VM was perhaps rebooted."
-            fi
+          if [ ! -s $CMDLINE  ]; then
+            log_it "Failed to receive the cmdline file via the qemu-guest-agent"
           fi
           ;;
      vmware)
@@ -142,65 +123,57 @@ get_systemvm_type() {
   export TYPE=$(grep -Po 'type=\K[a-zA-Z]*' $CMDLINE)
 }
 
-patch() {
-  local PATCH_MOUNT=/media/cdrom
-  local patchfile=$PATCH_MOUNT/cloud-scripts.tgz
-  local privkey=$PATCH_MOUNT/authorized_keys
-  local md5file=/var/cache/cloud/cloud-scripts-signature
-  local cdrom_dev=
-  mkdir -p $PATCH_MOUNT
-
-  if [ -e /dev/xvdd ]; then
-       cdrom_dev=/dev/xvdd
-  elif [ -e /dev/cdrom ]; then
-       cdrom_dev=/dev/cdrom
-  elif [ -e /dev/cdrom1 ]; then
-       cdrom_dev=/dev/cdrom1
-  elif [ -e /dev/cdrom2 ]; then
-       cdrom_dev=/dev/cdrom2
-  elif [ -e /dev/cdrom3 ]; then
-       cdrom_dev=/dev/cdrom3
-  fi
-
-  [ -f /var/cache/cloud/authorized_keys ] && privkey=/var/cache/cloud/authorized_keys
 
-  if [ -n "$cdrom_dev" ]; then
-    mount -o ro $cdrom_dev $PATCH_MOUNT
-    local oldmd5=
-    [ -f ${md5file} ] && oldmd5=$(cat ${md5file})
-    local newmd5=
-    [ -f ${patchfile} ] && newmd5=$(md5sum ${patchfile} | awk '{print $1}')
+patch_systemvm() {
+  local patchfile=$1
+  local backupfolder="/tmp/.conf.backup"
+  local logfile="/var/log/patchsystemvm.log"
+  if [ -f /usr/local/cloud/systemvm/conf/cloud.jks ]; then
+    rm -fr $backupfolder
+    mkdir -p $backupfolder
+    cp -r /usr/local/cloud/systemvm/conf/* $backupfolder/
+  fi
+  rm /usr/local/cloud/systemvm -rf
+  mkdir -p /usr/local/cloud/systemvm
+  echo "All" | unzip $patchfile -d /usr/local/cloud/systemvm >$logfile 2>&1
+  find /usr/local/cloud/systemvm/ -name \*.sh | xargs chmod 555
+  if [ -f $backupfolder/cloud.jks ]; then
+    cp -r $backupfolder/* /usr/local/cloud/systemvm/conf/
+    echo "Restored keystore file and certs using backup" >> $logfile
+  fi
+  rm -fr $backupfolder
+  # Import global cacerts into 'cloud' service's keystore
+  keytool -importkeystore -srckeystore /etc/ssl/certs/java/cacerts -destkeystore /usr/local/cloud/systemvm/certs/realhostip.keystore -srcstorepass changeit -deststorepass vmops.com -noprompt || true
+  return 0
+}
 
-    log_it "Scripts checksum detected: oldmd5=$oldmd5 newmd5=$newmd5"
-    if [ "$oldmd5" != "$newmd5" ] && [ -f ${patchfile} ] && [ "$newmd5" != "" ]
+patch() {
+  local PATCH_MOUNT=/media/cdrom
+  local logfile="/var/log/patchsystemvm.log"
+  if [ "$TYPE" == "consoleproxy" ] || [ "$TYPE" == "secstorage" ]  && [ -f ${PATCH_MOUNT}/agent.zip ] && [ -f /var/cache/cloud/patch.required ]
+  then
+    echo "Patching systemvm for cloud service with mount=$PATCH_MOUNT for type=$TYPE" >> $logfile
+    patch_systemvm ${PATCH_MOUNT}/agent.zip
+    if [ $? -gt 0 ]
     then
-      tar xzf $patchfile -C /
-      echo ${newmd5} > ${md5file}
-      log_it "Patched scripts using $patchfile"
-
-      log_it "Patching cloud service"
-      /opt/cloud/bin/setup/patchsystemvm.sh $PATCH_MOUNT $TYPE
+      echo "Failed to apply patch systemvm\n" >> $logfile
+      exit 1
     fi
-
-    [ -f $privkey ] && cp -f $privkey /root/.ssh/ && chmod go-rwx /root/.ssh/authorized_keys
-    umount $PATCH_MOUNT
   fi
 
+  rm -f /var/cache/cloud/patch.required
+  chmod -x /etc/systemd/system/cloud*.service
+  systemctl daemon-reload
+  umount $PATCH_MOUNT || true
+
   if [ -f /mnt/cmdline ]; then
     cat /mnt/cmdline > $CMDLINE
   fi
-
   return 0
 }
 
-start() {
-  log_it "Executing cloud-early-config"
-
-  # Clear /tmp for file lock
-  rm -f /tmp/*.lock
-  rm -f /tmp/rrouter_bumped
-  rm -f /root/.rnd
-  echo "" > /root/.ssh/known_hosts
+bootstrap() {
+  log_it "Bootstrapping systemvm appliance"
 
   export HYPERVISOR=$(hypervisor)
   [ $? -ne 0 ] && log_it "Failed to detect hypervisor type, bailing out of early init" && exit 10
@@ -214,16 +187,13 @@ start() {
   sysctl -p
 
   log_it "Configuring systemvm type=$TYPE"
-
   if [ -f "/opt/cloud/bin/setup/$TYPE.sh" ]; then
       /opt/cloud/bin/setup/$TYPE.sh
   else
       /opt/cloud/bin/setup/default.sh
   fi
-
   log_it "Finished setting up systemvm"
-
   exit 0
 }
 
-start
+bootstrap
diff --git a/systemvm/debian/opt/cloud/bin/setup/cloud-early-config b/systemvm/debian/opt/cloud/bin/setup/cloud-early-config
index 6aa0314..02593a3 100755
--- a/systemvm/debian/opt/cloud/bin/setup/cloud-early-config
+++ b/systemvm/debian/opt/cloud/bin/setup/cloud-early-config
@@ -16,10 +16,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
-#set -x
-#exec 3>&0 4>&1 > /var/log/test.log 2>&1
 PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
-CMDLINE=/var/cache/cloud/cmdline
 
 # Clear boot up flag, it would be created by rc.local after boot up done
 mkdir -p /var/cache/cloud
@@ -34,114 +31,6 @@ log_it() {
   log_action_msg "$@"
 }
 
-hypervisor() {
-  if [ -d /proc/xen ]; then
-    mount -t xenfs none /proc/xen
-    $(dmesg | grep -q "Xen HVM")
-    if [ $? -eq 0 ]; then  # 1=PV,0=HVM
-      echo "xen-hvm" && return 0
-    else
-      echo "xen-pv" && return 0
-    fi
-  fi
-
-  [ -x /usr/sbin/virt-what ] && local facts=( $(virt-what) )
-  if [ "$facts" != "" ]; then
-    # Xen HVM is recognized as Hyperv when Viridian extensions are enabled
-    if [ "${facts[-1]}" == "xen-domU" ] && [ "${facts[0]}" == "hyperv" ]; then
-      echo "xen-hvm" && return 0
-    else
-      echo ${facts[-1]} && return 0
-    fi
-  fi
-
-  grep -q QEMU /proc/cpuinfo  && echo "kvm" && return 0
-  grep -q QEMU /var/log/messages && echo "kvm" && return 0
-
-  vmware-checkvm &> /dev/null && echo "vmware" && return 0
-
-  echo "unknown" && return 1
-}
-
-config_guest() {
-  if [ "$HYPERVISOR" == "kvm" ]
-  then
-    # Configure hot-plug
-    modprobe acpiphp || true
-    modprobe pci_hotplug || true
-    sed -i -e "/^s0:2345:respawn.*/d" /etc/inittab
-    sed -i -e "/6:23:respawn/a\s0:2345:respawn:/sbin/getty -L 115200 ttyS0 vt102" /etc/inittab
-  fi
-  [ ! -d /proc/xen ] && sed -i 's/^vc/#vc/' /etc/inittab && telinit q
-  [  -d /proc/xen ] && sed -i 's/^#vc/vc/' /etc/inittab && telinit q
-}
-
-get_boot_params() {
-  case $HYPERVISOR in
-     xen-pv|xen-domU)
-          cat /proc/cmdline > $CMDLINE
-          sed -i "s/%/ /g" $CMDLINE
-          ;;
-     xen-hvm)
-          if [ ! -f /usr/bin/xenstore-read ]; then
-            log_it "ERROR: xentools not installed, cannot found xenstore-read" && exit 5
-          fi
-          /usr/bin/xenstore-read vm-data/cloudstack/init > $CMDLINE
-          sed -i "s/%/ /g" $CMDLINE
-          ;;
-     kvm)
-          # Use any old cmdline as backup only
-          if [ -s $CMDLINE ]; then
-            mv $CMDLINE $CMDLINE.old
-            log_it "Found a non-empty old cmdline file"
-          fi
-          systemctl enable --now qemu-guest-agent
-          # Wait for $CMDLINE file to be written by the qemu-guest-agent
-          for i in {1..60}; do
-            if [ -s $CMDLINE ]; then
-              log_it "Received a new non-empty cmdline file from qemu-guest-agent"
-              break
-            fi
-            sleep 1
-          done
-          # Use any old cmdline only when new cmdline is not received
-          if [ -e $CMDLINE.old ]; then
-            if [ -s $CMDLINE  ]; then
-              rm $CMDLINE.old
-            else
-              mv $CMDLINE.old $CMDLINE
-              log_it "Using old cmdline file, VM was perhaps rebooted."
-            fi
-          fi
-          ;;
-     vmware)
-          vmtoolsd --cmd 'machine.id.get' > $CMDLINE
-          ;;
-     virtualpc|hyperv)
-          # Hyper-V is recognized as virtualpc hypervisor type. Boot args are passed using KVP Daemon
-          #waiting for the hv_kvp_daemon to start up
-          #sleep  need to fix the race condition of hv_kvp_daemon and cloud-early-config
-          [ -f /usr/sbin/hv_kvp_daemon ] && /usr/sbin/hv_kvp_daemon
-          sleep 5
-          cp -f /var/opt/hyperv/.kvp_pool_0 $CMDLINE
-          cat /dev/null > /var/opt/hyperv/.kvp_pool_0
-          ;;
-     virtualbox)
-          # Virtualbox is used to test the virtual router
-          # get the commandline from a dmistring  (yes, hacky!)
-          dmidecode | grep cmdline | sed 's/^.*cmdline://' > $CMDLINE
-          RV=$?
-          if [ $RV -ne 0 ] ; then
-            log_it "Failed to get cmdline from a virtualbox dmi property"
-          fi
-          ;;
-  esac
-}
-
-get_systemvm_type() {
-  export TYPE=$(grep -Po 'type=\K[a-zA-Z]*' $CMDLINE)
-}
-
 patch() {
   local PATCH_MOUNT=/media/cdrom
   local patchfile=$PATCH_MOUNT/cloud-scripts.tgz
@@ -162,7 +51,9 @@ patch() {
        cdrom_dev=/dev/cdrom3
   fi
 
-  [ -f /var/cache/cloud/authorized_keys ] && privkey=/var/cache/cloud/authorized_keys
+  if [ -f /var/cache/cloud/authorized_keys ]; then
+    privkey=/var/cache/cloud/authorized_keys
+  fi
 
   if [ -n "$cdrom_dev" ]; then
     mount -o ro $cdrom_dev $PATCH_MOUNT
@@ -177,17 +68,13 @@ patch() {
       tar xzf $patchfile -C /
       echo ${newmd5} > ${md5file}
       log_it "Patched scripts using $patchfile"
-
-      log_it "Patching cloud service"
-      /opt/cloud/bin/setup/patchsystemvm.sh $PATCH_MOUNT $TYPE
+      touch /var/cache/cloud/patch.required
     fi
 
-    [ -f $privkey ] && cp -f $privkey /root/.ssh/ && chmod go-rwx /root/.ssh/authorized_keys
-    umount $PATCH_MOUNT
-  fi
-
-  if [ -f /mnt/cmdline ]; then
-    cat /mnt/cmdline > $CMDLINE
+    if [ -f $privkey ]; then
+      cp -f $privkey /root/.ssh/
+      chmod go-rwx /root/.ssh/authorized_keys
+    fi
   fi
 
   return 0
@@ -202,27 +89,11 @@ start() {
   rm -f /root/.rnd
   echo "" > /root/.ssh/known_hosts
 
-  export HYPERVISOR=$(hypervisor)
-  [ $? -ne 0 ] && log_it "Failed to detect hypervisor type, bailing out of early init" && exit 10
-  log_it "Detected that we are running inside $HYPERVISOR"
-
-  config_guest
-  get_boot_params
-  get_systemvm_type
   patch
   sync
-  sysctl -p
-
-  log_it "Configuring systemvm type=$TYPE"
-
-  if [ -f "/opt/cloud/bin/setup/$TYPE.sh" ]; then
-      /opt/cloud/bin/setup/$TYPE.sh
-  else
-      /opt/cloud/bin/setup/default.sh
-  fi
+  /opt/cloud/bin/setup/bootstrap.sh
 
   log_it "Finished setting up systemvm"
-
   exit 0
 }
 
diff --git a/systemvm/debian/opt/cloud/bin/setup/patchsystemvm.sh b/systemvm/debian/opt/cloud/bin/setup/patchsystemvm.sh
deleted file mode 100755
index c0d6d81..0000000
--- a/systemvm/debian/opt/cloud/bin/setup/patchsystemvm.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-#set -x
-logfile="/var/log/patchsystemvm.log"
-
-# To use existing console proxy .zip-based package file
-patch_systemvm() {
-   local patchfile=$1
-   local backupfolder="/tmp/.conf.backup"
-   if [ -f /usr/local/cloud/systemvm/conf/cloud.jks ]; then
-      rm -fr $backupfolder
-      mkdir -p $backupfolder
-      cp -r /usr/local/cloud/systemvm/conf/* $backupfolder/
-   fi
-   rm /usr/local/cloud/systemvm -rf
-   mkdir -p /usr/local/cloud/systemvm
-   echo "All" | unzip $patchfile -d /usr/local/cloud/systemvm >$logfile 2>&1
-   find /usr/local/cloud/systemvm/ -name \*.sh | xargs chmod 555
-   if [ -f $backupfolder/cloud.jks ]; then
-      cp -r $backupfolder/* /usr/local/cloud/systemvm/conf/
-      echo "Restored keystore file and certs using backup" >> $logfile
-   fi
-   rm -fr $backupfolder
-   # Import global cacerts into 'cloud' service's keystore
-   keytool -importkeystore -srckeystore /etc/ssl/certs/java/cacerts -destkeystore /usr/local/cloud/systemvm/certs/realhostip.keystore -srcstorepass changeit -deststorepass vmops.com -noprompt || true
-   return 0
-}
-
-CMDLINE=/var/cache/cloud/cmdline
-PATCH_MOUNT=$1
-TYPE=$2
-
-# Refresh and setup systemd
-chmod -x /etc/systemd/system/cloud*.service
-systemctl daemon-reload
-
-echo "Patching systemvm for cloud service with mount=$PATCH_MOUNT for type=$TYPE" >> $logfile
-
-if [ "$TYPE" == "consoleproxy" ] || [ "$TYPE" == "secstorage" ]  && [ -f ${PATCH_MOUNT}/agent.zip ]
-then
-  patch_systemvm ${PATCH_MOUNT}/agent.zip
-  if [ $? -gt 0 ]
-  then
-    echo "Failed to apply patch systemvm\n" >> $logfile
-    exit 1
-  fi
-fi
diff --git a/systemvm/debian/opt/cloud/bin/setup/router.sh b/systemvm/debian/opt/cloud/bin/setup/router.sh
index 6bb3b6f..e1fe8cd 100755
--- a/systemvm/debian/opt/cloud/bin/setup/router.sh
+++ b/systemvm/debian/opt/cloud/bin/setup/router.sh
@@ -96,7 +96,9 @@ setup_router() {
   sed -i "s/-A INPUT -i eth0 -p tcp -m tcp --dport 53 -j ACCEPT/-A INPUT -i eth0 -p tcp -m tcp --dport 53 -s $DHCP_RANGE\/$CIDR_SIZE -j ACCEPT/g" /etc/iptables/rules.v4
 
   # Setup hourly logrotate
-  mv -n /etc/cron.daily/logrotate /etc/cron.hourly 2>&1
+  if [ -f /etc/cron.daily/logrotate ]; then
+    mv -n /etc/cron.daily/logrotate /etc/cron.hourly 2>&1
+  fi
 }
 
 routing_svcs
diff --git a/systemvm/debian/opt/cloud/bin/setup/vpcrouter.sh b/systemvm/debian/opt/cloud/bin/setup/vpcrouter.sh
index af111ad..9e6cdb7 100755
--- a/systemvm/debian/opt/cloud/bin/setup/vpcrouter.sh
+++ b/systemvm/debian/opt/cloud/bin/setup/vpcrouter.sh
@@ -108,8 +108,10 @@ EOF
       echo 0 > /var/cache/cloud/dnsmasq_managed_lease
   fi
 
-  #setup hourly logrotate
-  mv -n /etc/cron.daily/logrotate /etc/cron.hourly 2>&1
+  # Setup hourly logrotate
+  if [ -f /etc/cron.daily/logrotate ]; then
+    mv -n /etc/cron.daily/logrotate /etc/cron.hourly 2>&1
+  fi
 }
 
 routing_svcs
diff --git a/tools/appliance/systemvmtemplate/scripts/install_systemvm_packages.sh b/tools/appliance/systemvmtemplate/scripts/install_systemvm_packages.sh
index 585b38d..c855341 100644
--- a/tools/appliance/systemvmtemplate/scripts/install_systemvm_packages.sh
+++ b/tools/appliance/systemvmtemplate/scripts/install_systemvm_packages.sh
@@ -67,6 +67,7 @@ function install_packages() {
     libtcnative-1 libssl-dev libapr1-dev \
     python-flask \
     haproxy \
+    haveged \
     radvd \
     sharutils genisoimage aria2 \
     strongswan libcharon-extra-plugins libstrongswan-extra-plugins \