]> Frank Brehm's Git Trees - pixelpark/create-vmware-tpl.git/commitdiff
Starting with postinstall tasks
authorFrank Brehm <frank.brehm@pixelpark.com>
Thu, 12 Apr 2018 12:38:50 +0000 (14:38 +0200)
committerFrank Brehm <frank.brehm@pixelpark.com>
Thu, 12 Apr 2018 12:38:50 +0000 (14:38 +0200)
lib/cr_vmware_tpl/handler.py

index 7498ef8180d798e2182ecc1150f1db38d7578cfe..424d9ee4b7e37cf310a581ae5de6180544055901 100644 (file)
@@ -18,6 +18,7 @@ import random
 import time
 import datetime
 import socket
+import textwrap
 
 # Third party modules
 import six
@@ -37,7 +38,7 @@ from .obj import PpBaseObject
 
 from .config import CrTplConfiguration
 
-__version__ = '0.6.5'
+__version__ = '0.7.1'
 LOG = logging.getLogger(__name__)
 TZ = pytz.timezone('Europe/Berlin')
 
@@ -165,6 +166,10 @@ class CrTplHandler(PpBaseObject):
         self.initial_sleep = 60
         self.interval_poll = 0.5
         self.interval_dot = 2
+        self.private_ssh_key = os.path.join(self.base_dir, 'keys', 'id_rsa_cr_vmw_tpl')
+        self.ssh_port = 22
+        self.ssh_user = 'root'
+        self.ssh_timeout = 30
 
         if initialized:
             self.initialized = True
@@ -212,6 +217,7 @@ class CrTplHandler(PpBaseObject):
                     "Could not find VM after creating.")
             self.poweron_vm()
             self.wait_for_finish_install()
+            self.post_install_tasks_ssh()
         finally:
             LOG.debug("Disconnecting from vSphere host {h}:{p} ...".format(
                 h=self.config.vsphere_host, p=self.config.vsphere_port))
@@ -644,8 +650,6 @@ class CrTplHandler(PpBaseObject):
         print('', flush=True)
 
         LOG.debug("Waiting for SSH available ...")
-        if self.verbose <= 3:
-            print('   ==> ', end='', flush=True)
 
         addr_infos = socket.getaddrinfo(
             self.config.template_vm, 22, socket.AF_INET, socket.SOCK_STREAM)
@@ -660,6 +664,9 @@ class CrTplHandler(PpBaseObject):
         LOG.debug("Using address info: {}".format(pp(addr_info)))
         family, socktype, proto, canonname, sockaddr = addr_info
 
+        if self.verbose <= 3:
+            print('   ==> ', end='', flush=True)
+
         ssh_available = False
         cur_duration = cur_time - self.ts_start_install
         cur_time = time.time()
@@ -675,15 +682,14 @@ class CrTplHandler(PpBaseObject):
 
             cur_time = time.time()
             cur_duration = cur_time - self.ts_start_install
-            if (cur_time - last_dot) >= self.interval_dot:
-                if self.verbose <= 3:
-                    print('.', end='', flush=True)
-                    i += 1
-                    if i >= 60:
-                        print('', flush=True)
-                        print('       ', end='', flush=True)
-                        i = 0
-                    last_dot = cur_time
+            if (self.verbose <= 3) and ((cur_time - last_dot) >= self.interval_dot):
+                print('.', end='', flush=True)
+                i += 1
+                if i >= 60:
+                    print('', flush=True)
+                    print('       ', end='', flush=True)
+                    i = 0
+                last_dot = cur_time
 
             if self.verbose > 3:
                 LOG.debug("Trying to connect to {a} via TCP port {p} ...".format(
@@ -705,6 +711,9 @@ class CrTplHandler(PpBaseObject):
                     LOG.debug("Could not connect: {}".format(e))
                 continue
 
+            if self.verbose <= 3:
+                print('', flush=True)
+
             LOG.info("Connected to {a} via TCP port {p} ...".format(
                 a=sockaddr[0], p=sockaddr[1]))
             data = sock.recv(4096)
@@ -727,6 +736,61 @@ class CrTplHandler(PpBaseObject):
             raise ExpectedHandlerError(
                 "SSH not available after {:0.1f} seconds, giving up.".format(duration))
 
+    # -------------------------------------------------------------------------
+    def post_install_tasks_ssh(self):
+
+        LOG.info("Executing tasks per SSH after successful installation ...")
+
+        ssh = None
+
+        cmd = textwrap.dedent("""\
+        printf "Current host FQDN: "
+        hostname -f
+
+        if [ -f /var/log/post-install.log ] ; then
+            echo
+            echo "Post install log:"
+            echo
+            cat /var/log/post-install.log
+            echo
+            rm -v /var/log/post-install.log
+        fi
+
+        # sleep 2
+        # poweroff && logout
+        """)
+
+        try:
+
+            LOG.debug("Initializing paramiko SSHClient")
+            ssh = paramiko.SSHClient()
+            LOG.debug("Loading SSH system host keys.")
+            ssh.load_system_host_keys()
+            LOG.debug("Setting SSH missing host key policy to AutoAddPolicy.")
+            ssh.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
+
+            LOG.debug("Connecting to {h!r}, port {p} as {u!r} per SSH ...".format(
+                h=self.config.template_vm, p=self.ssh_port, u=self.ssh_user))
+            ssh.connect(
+                self.config.template_vm, port=self.ssh_port, timeout=self.ssh_timeout,
+                username=self.ssh_user, key_filename=self.private_ssh_key)
+
+            LOG.debug("Executing postinstall tasks ...")
+            if self.verbose > 1:
+                LOG.debug("Commands to execute:\n{}".format(cmd))
+
+            stdin, stdout, stderr = ssh.exec_command(
+                cmd, timeout=self.ssh_timeout)
+
+            LOG.debug("Output on STDOUT:\n{}".format(to_str(stdout.read())))
+            LOG.debug("Output on STDERR:\n{}".format(to_str(stderr.read())))
+
+        finally:
+            if ssh:
+                if self.verbose > 2:
+                    LOG.debug("Closing SSH connection.")
+                ssh.close()
+
 # =============================================================================
 
 if __name__ == "__main__":