From 0777d968d4e10009e4d20d8ea15fdf55568230cd Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Fri, 22 Sep 2023 10:47:23 +0200 Subject: [PATCH] Separating files dependend methods from cr_vmware_tpl.cobbler to cr_vmware_tpl.cobbler.files. --- lib/cr_vmware_tpl/cobbler/__init__.py | 226 +------------------------- lib/cr_vmware_tpl/cobbler/distro.py | 3 +- 2 files changed, 5 insertions(+), 224 deletions(-) diff --git a/lib/cr_vmware_tpl/cobbler/__init__.py b/lib/cr_vmware_tpl/cobbler/__init__.py index 19d9127..8f0faa6 100644 --- a/lib/cr_vmware_tpl/cobbler/__init__.py +++ b/lib/cr_vmware_tpl/cobbler/__init__.py @@ -39,6 +39,7 @@ from fb_tools.handler import BaseHandler from fb_tools.xlate import format_list from .distro import CobblerDistro +from .files import CobblerFiles from .. import print_section_start, print_section_end @@ -48,7 +49,7 @@ from ..errors import CobblerError, ExpectedCobblerError from ..xlate import XLATOR -__version__ = '0.11.0' +__version__ = '0.11.1' LOG = logging.getLogger(__name__) @@ -57,7 +58,7 @@ ngettext = XLATOR.ngettext # ============================================================================= -class Cobbler(BaseHandler, CobblerDistro): +class Cobbler(BaseHandler, CobblerDistro, CobblerFiles): """ A handler class for executing cobbler actions. """ @@ -204,58 +205,6 @@ class Cobbler(BaseHandler, CobblerDistro): LOG.debug(_("Completed SSH process:") + "\n{}".format(proc)) return proc - # ------------------------------------------------------------------------- - def scp_to(self, local_file, remote_file): - - ssh = None - - try: - - if self.verbose > 2: - LOG.debug(_("Initializing {} ...").format('paramiko SSHClient')) - ssh = paramiko.SSHClient() - if self.verbose > 2: - LOG.debug(_("Loading SSH system host keys.")) - ssh.load_system_host_keys() - if self.verbose > 2: - LOG.debug(_("Setting SSH missing host key policy to {}.").format('AutoAddPolicy')) - ssh.set_missing_host_key_policy(paramiko.client.AutoAddPolicy()) - - if self.verbose > 1: - LOG.debug(_("Connecting to {h!r}, port {p} as {u!r} per SSH ...").format( - h=self.host, p=self.ssh_port, u=self.ssh_user)) - - if self.simulate: - LOG.debug(_( - "Simulating SCP of {local!r} to {user}@{host}:{remote} ...").format( - local=str(local_file), user=self.ssh_user, - host=self.host, remote=str(remote_file))) - - else: - ssh.connect( - self.host, port=self.ssh_port, timeout=self.ssh_timeout, - username=self.ssh_user, key_filename=self.private_ssh_key) - - sftp = ssh.open_sftp() - - LOG.debug(_("SCP of {local!r} to {user}@{host}:{remote} ...").format( - local=str(local_file), user=self.ssh_user, - host=self.host, remote=str(remote_file))) - - sftp.put(str(local_file), str(remote_file)) - - except SSHException as e: - msg = _("Could not connect via {w} to {user}@{host}: {e}").format( - w='SCP', user=self.ssh_user, host=self.host, e=e) - raise ExpectedCobblerError(msg) - - finally: - sftp = None - if ssh: - if self.verbose > 2: - LOG.debug(_("Closing SSH connection.")) - ssh.close() - # ------------------------------------------------------------------------- def get_cobbler_version(self): """Trying to evaluate the version of Cobbler on the cobbler host.""" @@ -291,70 +240,6 @@ class Cobbler(BaseHandler, CobblerDistro): return cobbler_version - # ------------------------------------------------------------------------- - def check_remote_directory(self, rdir, desc=None): - - if self.verbose > 1: - msg = _("Checking existence of remote directory {!r} ...").format(str(rdir)) - LOG.debug(msg) - - cmd = textwrap.dedent("""\ - if [ -d {rdir!r} ] ; then - exit 0 - fi - exit 7 - """).format(rdir=str(rdir)) - - proc = self.exec_ssh(cmd) - if proc.returncode != 0: - dsc = _('Remote directory') - if desc: - dsc = desc - msg = _( - "{dsc} {rdir!r} on host {host!r} does not exists or is not a directory.").format( - dsc=dsc, rdir=str(rdir), host=self.host) - raise ExpectedCobblerError(msg) - - # ------------------------------------------------------------------------- - def ensure_remote_directory(self, rdir, desc=None): - - if self.verbose: - msg = _("Ensuring existence of remote directory {!r} ...").format(str(rdir)) - LOG.debug(msg) - - verb = '' - if self.verbose: - verb = " --verbose" - - cmd = textwrap.dedent("""\ - if [ -d {rdir!r} ] ; then - exit 0 - fi - if [ -e {rdir!r} ] ; then - echo "Path {rdir!r} exists, but is not a directory." >&2 - exit 7 - fi - mkdir --parents{verb} {rdir!r} - """).format(rdir=str(rdir), verb=verb) - - proc = self.exec_ssh(cmd) - if proc.returncode == 0: - if proc.stdout: - LOG.debug(_("Output:") + "\n{}".format(proc.stdout)) - else: - dsc = _('Remote directory') - if desc: - dsc = desc - err = _('No error message') - if proc.stderr: - err = proc.stderr - elif proc.stdout: - err = proc.stdout - msg = _( - "{dsc} {rdir!r} on host {host!r} could not be created: {err}").format( - dsc=dsc, rdir=str(rdir), host=self.host, err=err) - raise ExpectedCobblerError(msg) - # ------------------------------------------------------------------------- def get_profile_list(self): """Trying to get a list of all configured cobbler profiles.""" @@ -370,111 +255,6 @@ class Cobbler(BaseHandler, CobblerDistro): LOG.debug(_("Sorted list of found profiles:") + "\n{}".format(pp(profile_list))) return profile_list - # ------------------------------------------------------------------------- - def ensure_remote_file(self, local_file, remote_file, check_parent=True): - - if check_parent: - self.check_remote_directory(remote_file.parent) - - msg = _("Checking remote file {rfile!r} based on local {lfile!r} ...").format( - rfile=str(remote_file), lfile=str(local_file)) - LOG.debug(msg) - - if not local_file.exists() or not local_file.is_file(): - msg = _("Local file {!r} either not exists or is not a regular file.").format( - str(local_file)) - raise ExpectedCobblerError(msg) - local_file_content = local_file.read_bytes() - digest = hashlib.sha256(local_file_content).hexdigest() - if self.verbose > 1: - LOG.debug(_('{typ} sum of {ks!r} is: {dig}').format( - typ='SHA256', ks=str(local_file), dig=digest)) - - cmd = textwrap.dedent("""\ - if [ -f {rfile!r} ] ; then - digest=$(sha256sum {rfile!r} | awk '{{print $1}}') - echo "Digest: ${{digest}}" - if [ "${{digest}}" != {dig!r} ] ; then - echo "SHA256 sum does not match." >&2 - exit 4 - fi - exit 0 - else - exit 3 - fi - """).format(rfile=str(remote_file), dig=digest) - - proc = self.exec_ssh(cmd) - if proc.returncode == 0: - LOG.debug(_("Remote file {!r} has the correct content.").format( - str(remote_file))) - return - - msg = _("File {!r} has to be copied.").format(str(local_file)) - LOG.warn(msg) - - self.scp_to(local_file, remote_file) - - # ------------------------------------------------------------------------- - def get_remote_filecontent(self, remote_file): - - LOG.debug(_("Getting content of remote file {!r} ...").format(str(remote_file))) - - cmd = textwrap.dedent("""\ - if [ -f {rfile!r} ] ; then - cat {rfile!r} - else - echo "Remote file does not exists." >&2 - exit 7 - fi - """).format(rfile=str(remote_file)) - - proc = self.exec_ssh(cmd) - if proc.returncode: - err = _('No error message') - if proc.stderr: - err = proc.stderr - elif proc.stdout: - err = proc.stdout - msg = _( - "Error getting content of {rfile!r} on host {host!r} - " - "returncode was {rc}: {err}").format( - rfile=str(remote_file), host=self.host, rc=proc.returncode, err=err) - raise ExpectedCobblerError(msg) - - return proc.stdout - - # ------------------------------------------------------------------------- - def ensure_root_authkeys(self, tmp_auth_keys_file=None): - - bname = 'auth_keys_pp_betrieb' - if tmp_auth_keys_file: - local_file = tmp_auth_keys_file - else: - local_file = self.base_dir / 'keys' / bname - remote_file = self.cfg.cobbler_ws_docroot / self.cfg.cobbler_ws_rel_filesdir / bname - - self.ensure_remote_file(local_file, remote_file) - - # ------------------------------------------------------------------------- - def ensure_rsyslog_cfg_files(self): - - files_dir = self.base_dir / 'files' - docroot = self.cfg.cobbler_ws_docroot / self.cfg.cobbler_ws_rel_filesdir - remote_dir = docroot / self.cfg.system_status - - LOG.info(_("Ensuring currentness of rsyslog config files ...")) - print_section_start( - 'ensure_rsyslog_cfg_files', 'Ensuring rsyslog config files.', collapsed=True) - - for local_cfg_file in files_dir.glob('*rsyslog.conf*'): - remote_cfg_file = remote_dir / local_cfg_file.name - LOG.debug(_("Ensuring {loc!r} => {rem!r}.").format( - loc=str(local_cfg_file), rem=str(remote_cfg_file))) - self.ensure_remote_file(local_cfg_file, remote_cfg_file, check_parent=False) - - print_section_end('ensure_rsyslog_cfg_files') - # ------------------------------------------------------------------------- def ensure_profile_ks(self): diff --git a/lib/cr_vmware_tpl/cobbler/distro.py b/lib/cr_vmware_tpl/cobbler/distro.py index c35233f..811f909 100644 --- a/lib/cr_vmware_tpl/cobbler/distro.py +++ b/lib/cr_vmware_tpl/cobbler/distro.py @@ -4,13 +4,14 @@ @author: Frank Brehm @contact: frank.brehm@pixelpark.com @copyright: © 2023 by Frank Brehm, Berlin -@summary: A mixin module forthe Cobbler class +@summary: A mixin module for the Cobbler class for repo dependend methods. """ from __future__ import absolute_import, print_function # Standard modules import logging +# Third party modules from fb_tools.common import pp, to_str, is_sequence, to_bool from fb_tools.xlate import format_list -- 2.39.5