]> Frank Brehm's Git Trees - pixelpark/create-vmware-tpl.git/commitdiff
Implementing changing of an existing profile
authorFrank Brehm <frank.brehm@pixelpark.com>
Fri, 29 May 2020 13:13:00 +0000 (15:13 +0200)
committerFrank Brehm <frank.brehm@pixelpark.com>
Fri, 29 May 2020 13:13:00 +0000 (15:13 +0200)
lib/cr_vmware_tpl/cobbler.py

index efbe9f9a76fdea704fa124ce3148a94b9cefba74..7328e3053bba004591621134c325dc197ddfec00 100644 (file)
@@ -17,6 +17,8 @@ import json
 import hashlib
 import textwrap
 
+from json import JSONDecodeError
+
 # Third party modules
 import paramiko
 from paramiko.ssh_exception import SSHException
@@ -35,7 +37,7 @@ from .config import CrTplConfiguration
 
 from .xlate import XLATOR
 
-__version__ = '0.3.10'
+__version__ = '0.4.0'
 
 LOG = logging.getLogger(__name__)
 
@@ -270,8 +272,6 @@ class Cobbler(BaseHandler):
                     dsc=dsc, rdir=str(rdir), host=self.host)
             raise ExpectedCobblerError(msg)
 
-
-
     # -------------------------------------------------------------------------
     def get_distro_list(self):
         """Trying to get a list of all configured distros."""
@@ -349,6 +349,35 @@ class Cobbler(BaseHandler):
 
         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):
 
@@ -390,6 +419,89 @@ class Cobbler(BaseHandler):
         distro = self.config.cobbler_distro
 
         LOG.debug(_("Checking existing profile {!r} ...").format(profile))
+        remote_file = (
+            self.config.cobbler_rootdir / 'config' / 'profiles.d' / (
+                self.config.cobbler_profile + '.json'))
+
+        fcontent = self.get_remote_filecontent(remote_file)
+        if self.verbose > 2:
+            LOG.debug(_("Got content of remote {rfile!r}:\n{cont}").format(
+                rfile=str(remote_file), cont=fcontent))
+
+        try:
+            js = json.loads(fcontent)
+        except JSONDecodeError as e:
+            msg = _("Error interpreting JS: {}").format(e)
+            raise ExpectedCobblerError(msg)
+
+        if self.verbose > 1:
+            LOG.debug(_("Got json object for profile {name!r}:\n{obj}").format(
+                name=profile, obj=pp(js)))
+
+        self._change_profile(js)
+
+    # -------------------------------------------------------------------------
+    def _change_profile(self, js):
+
+        profile = self.config.cobbler_profile
+        distro = self.config.cobbler_distro
+
+        args = []
+
+        if js['distro'] != distro:
+            args.append('--distro')
+            args.append(distro)
+
+        if not js['enable_menu']:
+            args.append('--enable-menu')
+            args.append('1')
+
+        if js['kickstart'] != str(self.config.cobbler_profile_ks):
+            args.append('--kickstart')
+            args.append(str(self.config.cobbler_profile_ks))
+
+        if 'inst.sshd' not in js['kernel_options']:
+            args.append('--kopts')
+            args.append('inst.sshd')
+
+        if js['repos'] != self.config.cobbler_profile_repos:
+            args.append('--repos')
+            args.append(' '.join(self.config.cobbler_profile_repos))
+
+        os_id = self.config.os_id
+        comment = "Profile for creating a {} profile.".format(os_id)
+        if js['comment'] != comment:
+            args.append('--comment')
+            args.append(comment)
+
+        if js['name_servers'] != self.config.cobbler_nameservers:
+            args.append('--name-servers')
+            args.append(' '.join(self.config.cobbler_nameservers))
+
+        if js['name_servers_search'] != self.config.cobbler_dns_search:
+            args.append('--name-servers-search')
+            args.append(' '.join(self.config.cobbler_dns_search))
+
+        if self.verbose:
+            LOG.debug("Args for 'profile edit:\n{}".format(pp(args)))
+
+        if not args:
+            LOG.debug(_("No need for changing profile {!r}").format(profile))
+            return
+
+        args = ['profile', 'edit', '--name', profile] + args
+
+        proc = self.exec_cobbler(args)
+
+        if proc.returncode:
+            err = _('No error message')
+            if proc.stderr:
+                err = proc.stderr
+            elif proc.stdout:
+                err = proc.stdout
+            msg = _("Error editing a cobbler profile - returncode was {rc}: {err}").format(
+                rc=proc.returncode, err=err)
+            raise ExpectedCobblerError(msg)
 
     # -------------------------------------------------------------------------
     def add_profile(self):