From 116f99192dba057f71fae73218e86fb1a31a4f41 Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Mon, 16 Apr 2018 15:53:39 +0200 Subject: [PATCH] Shut down VM per SSH command --- lib/cr_vmware_tpl/app.py | 9 ++- lib/cr_vmware_tpl/handler.py | 110 +++++++++++++++++++++++++++++------ 2 files changed, 101 insertions(+), 18 deletions(-) diff --git a/lib/cr_vmware_tpl/app.py b/lib/cr_vmware_tpl/app.py index 157d1f3..7adf0f3 100644 --- a/lib/cr_vmware_tpl/app.py +++ b/lib/cr_vmware_tpl/app.py @@ -34,7 +34,7 @@ from .config import CrTplConfiguration from .handler import ExpectedHandlerError, CrTplHandler -__version__ = '0.4.1' +__version__ = '0.4.2' LOG = logging.getLogger(__name__) @@ -362,6 +362,13 @@ class CrTplApplication(PpBaseObject): root_logger.addHandler(lh_console) + if self.verbose < 3: + paramiko_logger = logging.getLogger('paramiko.transport') + if self.verbose < 1: + paramiko_logger.setLevel(logging.WARNING) + else: + paramiko_logger.setLevel(logging.INFO) + return # ------------------------------------------------------------------------- diff --git a/lib/cr_vmware_tpl/handler.py b/lib/cr_vmware_tpl/handler.py index 61c5a43..5ed0eae 100644 --- a/lib/cr_vmware_tpl/handler.py +++ b/lib/cr_vmware_tpl/handler.py @@ -38,7 +38,7 @@ from .obj import PpBaseObject from .config import CrTplConfiguration -__version__ = '0.7.5' +__version__ = '0.7.6' LOG = logging.getLogger(__name__) TZ = pytz.timezone('Europe/Berlin') @@ -821,14 +821,6 @@ class CrTplHandler(PpBaseObject): rm -v /var/log/post-install.log fi - echo - echo "Cleaning up /root/.ssh/authorized_keys ..." - cat /root/.ssh/authorized_keys | grep -v create-vmware-tpl@pixelpark.com > /tmp/authorized_keys - mv -v /tmp/authorized_keys /root/.ssh/authorized_keys - - echo "Removing SSH host keys ..." - rm -v /etc/ssh/ssh_host_* - """) try: @@ -865,7 +857,55 @@ class CrTplHandler(PpBaseObject): # ------------------------------------------------------------------------- def poweroff_vm(self): - LOG.info("Powering off VM {!r} ...".format(self.config.template_vm)) + wait_for_shutdown = 15 + + LOG.debug("Waiting for {} seconds for shutting down:".format(wait_for_shutdown)) + print(' ==> ', end='', flush=True) + + start_waiting = time.time() + cur_time = start_waiting + cur_duration = 0 + last_dot = cur_time + + while cur_duration <= wait_for_shutdown: + time.sleep(0.1) + cur_time = time.time() + if (cur_time - last_dot) >= 1: + print('.', end='', flush=True) + last_dot = cur_time + cur_duration = cur_time - start_waiting + print('', flush=True) + + LOG.info("Powering off VM {!r} per SSH ...".format(self.config.template_vm)) + + ssh = None + + cmd = textwrap.dedent("""\ + echo + echo "-----------------------------------------------------------" + echo "Cleaning up /root/.ssh/authorized_keys ..." + afile="/root/.ssh/authorized_keys" + tfile="/tmp/authorized_keys" + pattern="create-vmware-tpl@pixelpark.com" + + cat "${afile}" | grep -v "${pattern}" > "${tfile}" + mv -v "${tfile}" "${afile}" + + echo + echo "-----------------------------------------------------------" + echo "Removing SSH host keys ..." + rm -v /etc/ssh/ssh_host_* + + echo + echo "Sleeping some seconds ..." + sleep 3 + + echo + echo "-----------------------------------------------------------" + echo "Powering off ..." + poweroff && logout + + """) vm = self.get_temp_tpl_vm() guest_state = vm.guest.guestState @@ -879,26 +919,62 @@ class CrTplHandler(PpBaseObject): "Cannot shut down VM {h!r}, is currently in state {s!r}.".format( h=self.config.template_vm, s=guest_state)) - LOG.debug("Shutting down VM {!r} ...".format(self.config.template_vm)) - start_shutdown = time.time() +# LOG.debug("Shutting down VM {!r} ...".format(self.config.template_vm)) +# start_shutdown = time.time() + + 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 poweroff ...") + 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() + cur_diff = 0 - vm.ShutdownGuest() + start_shutdown = time.time() cur_time = start_shutdown last_dot = cur_time i = 0 LOG.debug("Waiting for successful shut down of VM ...") - if self.verbose <= 2: + if self.verbose <= 3: print(' ==> ', end='', flush=True) while guest_state.strip().lower() != "notrunning": time.sleep(0.2) + dot = '.' + if guest_state.lower().strip() != 'running': + dot = '+' + cur_time = time.time() cur_diff = cur_time - start_shutdown - if (self.verbose <= 2) and ((cur_time - last_dot) >= self.interval_dot): - print('.', end='', flush=True) + if (self.verbose <= 3) and ((cur_time - last_dot) >= self.interval_dot): + print(dot, end='', flush=True) i += 1 if i >= 60: print('', flush=True) @@ -908,7 +984,7 @@ class CrTplHandler(PpBaseObject): vm = self.get_temp_tpl_vm() guest_state = vm.guest.guestState - if self.verbose > 2: + if self.verbose > 3: LOG.debug("Still waiting for completing shutdown, current state is {!r}.".format( guest_state)) if guest_state.strip().lower() == "notrunning": -- 2.39.5