]> Frank Brehm's Git Trees - pixelpark/create-vmware-tpl.git/commitdiff
Refactoring lib/cr_vmware_tpl/handler.py for remote executing
authorFrank Brehm <frank.brehm@pixelpark.com>
Fri, 7 Jan 2022 11:08:53 +0000 (12:08 +0100)
committerFrank Brehm <frank.brehm@pixelpark.com>
Fri, 7 Jan 2022 11:08:53 +0000 (12:08 +0100)
lib/cr_vmware_tpl/handler.py

index 6b91e4ef1c5b1b6e111820af965966e0a83038a9..55b36c0f60c9eccea6f444368687dcafb59dd9aa 100644 (file)
@@ -46,7 +46,7 @@ from .cobbler import Cobbler
 
 from .xlate import XLATOR
 
-__version__ = '1.8.6'
+__version__ = '1.9.0'
 
 LOG = logging.getLogger(__name__)
 TZ = pytz.timezone('Europe/Berlin')
@@ -335,6 +335,7 @@ class CrTplHandler(BaseHandler):
             self.eval_tpl_ip()
             self.wait_for_finish_install()
 
+            self.show_install_log()
             self.get_postinstall_error()
             if self.abort:
                 LOG.warn(_("Aborting after creation of template VM."))
@@ -759,16 +760,11 @@ class CrTplHandler(BaseHandler):
                 _("SSH not available after {:0.1f} seconds, giving up.").format(duration))
 
     # -------------------------------------------------------------------------
-    def get_postinstall_error(self):
-
-        LOG.info(_("Trying to get possible post-installation errors ..."))
+    def exec_remote(self, cmd):
 
         ssh = None
-        cmd = textwrap.dedent("""\
-        if [ -f /root/postinst-error.txt ] ; then
-            cat /root/postinst-error.txt
-        fi
-        """)
+        result = {'out': None, 'err': None}
+        err = None
 
         try:
 
@@ -785,23 +781,16 @@ class CrTplHandler(BaseHandler):
                 self.tpl_ip, port=self.ssh_port, timeout=self.ssh_timeout,
                 username=self.ssh_user, key_filename=self.private_ssh_key)
 
-            LOG.debug(_("Trying to read {!r} ...").format('/root/postinst-error.txt'))
             if self.verbose > 1:
                 LOG.debug(_("Commands to execute:") + '\n' + cmd)
 
             stdin, stdout, stderr = ssh.exec_command(
                 cmd, timeout=self.ssh_timeout)
 
-            output = to_str(stdout.read()).strip()
-            err = to_str(stderr.read()).strip()
+            result['out'] = to_str(stdout.read()).strip()
+            result['err'] = to_str(stderr.read()).strip()
 
-            LOG.debug(_("Output on {}:").format('STDERR') + '\n' + str(err))
-
-            if output:
-                self.postinstall_errors = output
-                LOG.error(_("Got postinstall errors:") + '\n' + output)
-            else:
-                LOG.info(_("No postinstall errors found."))
+            LOG.debug(_("Output on {}:").format('STDERR') + '\n' + result['err'])
 
         finally:
             if ssh:
@@ -809,6 +798,58 @@ class CrTplHandler(BaseHandler):
                     LOG.debug(_("Closing SSH connection."))
                 ssh.close()
 
+        return result
+
+    # -------------------------------------------------------------------------
+    def show_install_log(self):
+
+        LOG.info(_("Showing post install log ..."))
+        install_logfile = '/var/log/anaconda/post-install.log'
+
+        cmd = textwrap.dedent("""\
+        if [ -f {log} ] ; then
+            echo "-----------------------------------------------------------"
+            cat {log}
+            echo "-----------------------------------------------------------"
+            echo
+        else
+            echo "Post install log {log} not found!" >&2
+        fi
+
+        """).format(log=install_logfile)
+
+        result = self.exec_remote(cmd)
+
+        if result['err']:
+            LOG.error(result['err'])
+            if self.postinstall_errors:
+                self.postinstall_errors += result['err']
+            else:
+                self.postinstall_errors = result['err']
+        else:
+            LOG.debug("Post install log:\n\n" + result['out'])
+
+    # -------------------------------------------------------------------------
+    def get_postinstall_error(self):
+
+        LOG.info(_("Trying to get possible post-installation errors ..."))
+
+        cmd = textwrap.dedent("""\
+        if [ -f /root/postinst-error.txt ] ; then
+            cat /root/postinst-error.txt
+        fi
+        """)
+
+        result = self.exec_remote(cmd)
+        if result['out']:
+            if self.postinstall_errors:
+                self.postinstall_errors += result['out']
+            else:
+                self.postinstall_errors = result['out']
+            LOG.error(_("Got postinstall errors:") + '\n' + result['out'])
+        else:
+            LOG.info(_("No postinstall errors found."))
+
         if self.postinstall_errors:
             LOG.warn(_("Template VM {!r} has to be removed.").format(self.tpl_ip))
 
@@ -816,8 +857,7 @@ class CrTplHandler(BaseHandler):
     def post_install_tasks_ssh(self):
 
         LOG.info(_("Executing tasks per SSH after installation ..."))
-
-        ssh = None
+        print_section_start('post_install_tasks', 'Exec post install tasks ...', collapsed=True)
 
         logfiles = (
             '/var/log/boot.log',
@@ -835,23 +875,16 @@ class CrTplHandler(BaseHandler):
         printf "Current host FQDN: "
         hostname -f
 
-        echo
-        echo "-----------------------------------------------------------"
-        if [ -f /root/original-ks.cfg ] ; then
-            echo "Moving /root/original-ks.cfg => /var/log/anaconda/ ..."
-            mv -v /root/original-ks.cfg /var/log/anaconda/
-        else
-            echo "File /root/original-ks.cfg not found."
-        fi
-
-        echo
-        echo "-----------------------------------------------------------"
-        if [ -f /root/anaconda-ks.cfg ] ; then
-            echo "Moving /root/anaconda-ks.cfg => /var/log/anaconda/ ..."
-            mv -v /root/anaconda-ks.cfg /var/log/anaconda/
-        else
-            echo "File /root/anakonda-ks.cfg not found."
-        fi
+        for ks_cfg in "/root/original-ks.cfg" "/root/anaconda-ks.cfg" ; do
+            echo
+            echo "-----------------------------------------------------------"
+            if [ -f "${ks_cfg}" ] ; then
+                echo "Moving ${ks_cfg} => /var/log/anaconda/ ..."
+                mv -v "${ks_cfg}" /var/log/anaconda/
+            else
+                echo "File ${ks_cfg} not found." >&2
+            fi
+        done
 
         for f in @@@LOGFILES@@@ ; do
             if [ -f "${f}" ] ; then
@@ -859,57 +892,17 @@ class CrTplHandler(BaseHandler):
                 cp /dev/null "${f}"
             fi
         done
-
-        if [ -f /var/log/anaconda/post-install.log ] ; then
-            echo
-            echo "Post install log:"
-            echo
-            echo "-----------------------------------------------------------"
-            cat /var/log/anaconda/post-install.log
-            echo "-----------------------------------------------------------"
-            echo
-        else
-            echo
-            echo "###########################################################"
-            echo
-            echo "Post install log not found!"
-            echo
-            echo "###########################################################"
-            echo
-        fi
-
         """).replace('@@@LOGFILES@@@', ' '.join(logfiles))
 
-        try:
+        result = self.exec_remote(cmd)
+        LOG.debug(_("Output on {}:").format('STDOUT') + '\n' + result['out'])
+        if not result['err']:
+            LOG.debug(_("No output on {}.").format('STDERR'))
 
-            LOG.debug(_("Initializing {} ...").format('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 {}.").format('AutoAddPolicy'))
-            ssh.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
+        print_section_end('post_install_tasks')
 
-            LOG.debug(_("Connecting to {h!r}, port {p} as {u!r} per SSH ...").format(
-                h=self.tpl_ip, p=self.ssh_port, u=self.ssh_user))
-            ssh.connect(
-                self.tpl_ip, 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' + cmd)
-
-            stdin, stdout, stderr = ssh.exec_command(
-                cmd, timeout=self.ssh_timeout)
-
-            LOG.debug(_("Output on {}:").format('STDOUT') + '\n' + to_str(stdout.read()))
-            LOG.debug(_("Output on {}:").format('STDERR') + '\n' + to_str(stderr.read()))
-
-        finally:
-            if ssh:
-                if self.verbose > 2:
-                    LOG.debug(_("Closing SSH connection."))
-                ssh.close()
+        if result['err']:
+            LOG.warn(_("Output on {}:").format('STDERR') + '\n' + result['err'])
 
     # -------------------------------------------------------------------------
     def poweroff_vm(self):
@@ -939,8 +932,6 @@ class CrTplHandler(BaseHandler):
 
         LOG.info(_("Last actions before powering off VM {!r} ...").format(self.tpl_ip))
 
-        ssh = None
-
         cmd = textwrap.dedent("""\
         echo
         echo "-----------------------------------------------------------"
@@ -981,37 +972,17 @@ class CrTplHandler(BaseHandler):
                     h=self.tpl_ip, s=power_state))
 
         LOG.info(_("Powering off VM {!r} per SSH ...").format(self.tpl_ip))
+        print_section_start('poweroff', 'Powering off VM ...', collapsed=True)
+        result = self.exec_remote(cmd)
 
-        try:
-
-            LOG.debug(_("Initializing {} ...").format('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 {}.").format('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.tpl_ip, p=self.ssh_port, u=self.ssh_user))
-            ssh.connect(
-                self.tpl_ip, port=self.ssh_port, timeout=self.ssh_timeout,
-                username=self.ssh_user, key_filename=self.private_ssh_key)
-
-            LOG.debug(_("Executing {} ...").format('poweroff'))
-            if self.verbose > 1:
-                LOG.debug(_("Commands to execute:") + '\n' + cmd)
+        LOG.debug(_("Output on {}:").format('STDOUT') + '\n' + result['out'])
+        if not result['err']:
+            LOG.debug(_("No output on {}.").format('STDERR'))
 
-            stdin, stdout, stderr = ssh.exec_command(
-                cmd, timeout=self.ssh_timeout)
+        print_section_end('poweroff')
 
-            LOG.debug(_("Output on {}:").format('STDOUT') + '\n' + to_str(stdout.read()))
-            LOG.debug(_("Output on {}:").format('STDERR') + '\n' + to_str(stderr.read()))
-
-        finally:
-            if ssh:
-                if self.verbose > 2:
-                    LOG.debug(_("Closing SSH connection."))
-                ssh.close()
+        if result['err']:
+            LOG.warn(_("Output on {}:").format('STDERR') + '\n' + result['err'])
 
         cur_diff = 0
         start_shutdown = time.time()
@@ -1081,6 +1052,7 @@ class CrTplHandler(BaseHandler):
     def rotate_templates(self):
 
         LOG.info(_("Searching for existing templates and rotate them ..."))
+        print_section_start('rotate_templates', "Rotating templates ...", collapsed=True)
         re_is_numeric = re.compile(r'^\s*(\d+)\s*$')
 
         pattern_tpl = r'^' + re.escape(self.config.template_name)
@@ -1163,11 +1135,15 @@ class CrTplHandler(BaseHandler):
                 tname = tpl_name.strip().lower()
                 new_template_names[tname] = 1
 
+        print_section_end('rotate_templates')
+
     # -------------------------------------------------------------------------
     def rename_and_change_vm(self):
 
         LOG.info(_("Renaming VM {o!r} => {n!r} ...").format(
             o=self.tpl_vm_fqdn, n=self.config.template_name))
+        print_section_start(
+            'rename_and_change_vm', "Renaming VM and mark as template ...", collapsed=True)
 
         vm = self.get_temp_tpl_vm()
         task = vm.Rename_Task(self.config.template_name)
@@ -1178,6 +1154,7 @@ class CrTplHandler(BaseHandler):
             self.config.template_name))
         vm.MarkAsTemplate()
         LOG.debug(_("Object {!r} is now a VMWare template.").format(self.config.template_name))
+        print_section_end('rename_and_change_vm')
 
 
 # =============================================================================