import hashlib
import textwrap
+from json import JSONDecodeError
+
# Third party modules
import paramiko
from paramiko.ssh_exception import SSHException
from .xlate import XLATOR
-__version__ = '0.3.10'
+__version__ = '0.4.0'
LOG = logging.getLogger(__name__)
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."""
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):
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):