]> Frank Brehm's Git Trees - pixelpark/create-vmware-tpl.git/commitdiff
Separating profile dependend methods from cr_vmware_tpl.cobbler to cr_vmware_tpl...
authorFrank Brehm <frank.brehm@pixelpark.com>
Fri, 22 Sep 2023 09:00:53 +0000 (11:00 +0200)
committerFrank Brehm <frank.brehm@pixelpark.com>
Fri, 22 Sep 2023 09:00:53 +0000 (11:00 +0200)
lib/cr_vmware_tpl/cobbler/__init__.py
lib/cr_vmware_tpl/cobbler/profile.py [new file with mode: 0644]

index 8f0faa66c8abf16876d13565c743b4d7d598e498..21e25daa5f6d6ba5b8c97090c5c9822c26de83cc 100644 (file)
@@ -40,6 +40,7 @@ from fb_tools.xlate import format_list
 
 from .distro import CobblerDistro
 from .files import CobblerFiles
+from .profile import CobblerProfile
 
 from .. import print_section_start, print_section_end
 
@@ -49,7 +50,7 @@ from ..errors import CobblerError, ExpectedCobblerError
 
 from ..xlate import XLATOR
 
-__version__ = '0.11.1'
+__version__ = '0.11.2'
 
 LOG = logging.getLogger(__name__)
 
@@ -58,7 +59,7 @@ ngettext = XLATOR.ngettext
 
 
 # =============================================================================
-class Cobbler(BaseHandler, CobblerDistro, CobblerFiles):
+class Cobbler(BaseHandler, CobblerDistro, CobblerFiles, CobblerProfile):
     """
     A handler class for executing cobbler actions.
     """
@@ -240,258 +241,6 @@ class Cobbler(BaseHandler, CobblerDistro, CobblerFiles):
 
         return cobbler_version
 
-    # -------------------------------------------------------------------------
-    def get_profile_list(self):
-        """Trying to get a list of all configured cobbler profiles."""
-
-        profile_list = []
-        proc = self.exec_cobbler(('profile', 'list'), no_simulate=True, show_output=False)
-        for line in proc.stdout.splitlines():
-            profile = line.strip()
-            if profile:
-                profile_list.append(profile)
-        profile_list.sort(key=str.lower)
-        if self.verbose > 1:
-            LOG.debug(_("Sorted list of found profiles:") + "\n{}".format(pp(profile_list)))
-        return profile_list
-
-    # -------------------------------------------------------------------------
-    def ensure_profile_ks(self):
-
-        ks_template_name = self.cfg.current_distro.ks_template
-
-        LOG.info(_("Using {!r} as a template for the kickstart file.").format(
-            './templates/' + ks_template_name))
-
-        prefix = 'tmp.' + self.cfg.cobbler_profile + '.'
-        (fh, tmp_ks) = tempfile.mkstemp(prefix=prefix, suffix='.ks', text=True)
-        os.close(fh)
-        self.local_ks_file = Path(tmp_ks)
-        LOG.debug(_("Using temporary kickstart file {!r}.").format(tmp_ks))
-
-        snippet_lst = []
-        for snippet in sorted(self.cfg.current_distro.snippets.values(), key=str.lower):
-            snippet_lst.append(snippet)
-
-        jinja_env = jinja2.Environment(
-            loader=jinja2.FileSystemLoader(str(self.base_dir / 'templates')),
-            autoescape=jinja2.select_autoescape(),
-        )
-        ks_template = jinja_env.get_template(ks_template_name)
-        ks_content = ks_template.render(
-            distro=self.cfg.current_distro, snippets=snippet_lst) + '\n\n'
-        if self.verbose > 1:
-            LOG.debug(_("Generated kickstart file content:") + '\n' + ks_content)
-
-        self.local_ks_file.write_text(ks_content)
-
-        remote_ks = self.cfg.cobbler_profile_ks
-        LOG.info(_("Ensuring currentness of profile kickstart script {!r}.").format(
-            str(remote_ks)))
-
-        self.ensure_remote_file(self.local_ks_file, remote_ks)
-
-        LOG.debug(_("Removing {!r} ...").format(str(self.local_ks_file)))
-        self.local_ks_file.unlink()
-        self.local_ks_file = None
-
-    # -------------------------------------------------------------------------
-    def ensure_profile(self):
-        """Ensure the existence and the correctnes of the given profile."""
-
-        profile = self.cfg.cobbler_profile
-
-        LOG.info(_("Ensuring profile {!r} ...").format(profile))
-        print_section_start(
-            'cobbler_ensure_profile', 'Ensuring profile.', collapsed=True)
-
-        profile_list = self.get_profile_list()
-
-        if profile in profile_list:
-            self.change_profile()
-        else:
-            self.add_profile()
-
-        print_section_end('cobbler_ensure_profile')
-
-    # -------------------------------------------------------------------------
-    def change_profile(self):
-        """Ensure correctnes of an existing profile."""
-
-        profile = self.cfg.cobbler_profile
-
-        LOG.debug(_("Checking existing profile {!r} ...").format(profile))
-
-        profile_vars = self.get_profile_vars(profile)
-
-        if self.verbose > 1:
-            LOG.debug(_("Got profile variables:") + '\n' + pp(profile_vars))
-        self._change_profile(profile_vars)
-
-    # -------------------------------------------------------------------------
-    def get_profile_vars(self, profile):
-
-        vars_out = '[main]\n'
-
-        kwargs = {
-            'allow_no_value': True,
-            'strict': False,
-        }
-
-        cmd = ('profile', 'dumpvars', '--name', profile)
-
-        proc = self.exec_cobbler(cmd, no_simulate=True, show_output=False)
-        vars_out += proc.stdout
-
-        parser = configparser.RawConfigParser(**kwargs)
-        try:
-            parser.read_string(vars_out)
-        except Exception as e:
-            msg = _("Got {what} on reading and parsing of profile {p!r}:").format(
-                what=e.__class__.__name__, p=profile)
-            msg += ' ' + str(e)
-            raise ExpectedCobblerError(msg)
-
-        data = {}
-
-        for (key, value) in parser.items('main'):
-            k = key.lower()
-            data[k] = value
-
-        return data
-
-    # -------------------------------------------------------------------------
-    def _change_profile(self, profile_vars):
-
-        profile = self.cfg.cobbler_profile
-        distro = self.cfg.cobbler_distro
-        distro_info = self.cfg.current_distro
-        status = self.cfg.system_status
-
-        LOG.debug(_("Checking existing profile {n!r} ({d}) ...").format(
-            n=profile, d=distro_info.description))
-
-        repos = []
-        if distro_info.repos:
-            repos = distro_info.repos.as_list()
-        repos_str = ' '.join(repos)
-
-        comment = "Profile for creating a {} VM.".format(distro_info.description)
-        name_servers = '[' + ', '.join(
-            map(lambda x: "'" + x + "'", self.cfg.cobbler_nameservers)) + ']'
-        dns_search = '[' + ', '.join(
-            map(lambda x: "'" + x + "'", self.cfg.cobbler_dns_search)) + ']'
-
-        args = []
-
-        if self.verbose > 1:
-            msg = _("Checking for distro:") + ' ' + distro
-            LOG.debug(msg)
-        if profile_vars['distro'] != distro:
-            args.append('--distro')
-            args.append(distro)
-
-        enable_menu = to_bool(profile_vars['enable_menu'])
-        if not enable_menu:
-            args.append('--enable-menu')
-            args.append('1')
-
-        if self.cfg.cobbler_major_version == 3:
-            if profile_vars['autoinstall'] != str(self.cfg.cobbler_profile_ks.name):
-                args.append('--autoinstall')
-                args.append(str(self.cfg.cobbler_profile_ks.name))
-        else:
-            if profile_vars['kickstart'] != str(self.cfg.cobbler_profile_ks):
-                args.append('--kickstart')
-                args.append(str(self.cfg.cobbler_profile_ks))
-
-        if self.verbose > 1:
-            msg = _("Checking for repos:") + ' ' + repos_str
-            LOG.debug(msg)
-        if profile_vars['repos'] != repos_str:
-            args.append('--repos')
-            args.append(repos_str)
-
-        if profile_vars['comment'] != comment:
-            args.append('--comment')
-            args.append(comment)
-
-        if self.verbose > 1:
-            msg = _("Checking for nameservers:") + ' ' + name_servers
-            LOG.debug(msg)
-        if profile_vars['name_servers'] != name_servers:
-            args.append('--name-servers')
-            args.append(' '.join(self.cfg.cobbler_nameservers))
-
-        if self.verbose > 1:
-            msg = _("Checking for DNS search domains:") + ' ' + dns_search
-            LOG.debug(msg)
-        if profile_vars['name_servers_search'] != dns_search:
-            args.append('--name-servers-search')
-            args.append(' '.join(self.cfg.cobbler_dns_search))
-
-        ks_meta_ok = True
-        ks_meta_vars = {}
-        if 'autoinstall_meta' in profile_vars:
-            ks_meta_vars = self.xform_ks_meta(profile_vars['autoinstall_meta'])
-        if 'ROOT_PWD_HASH' not in ks_meta_vars:
-            LOG.debug(_('Profile ks_meta {!r} is not ok.').format('ROOT_PWD_HASH'))
-            ks_meta_ok = False
-        if ('SWAP_SIZE_MB' not in ks_meta_vars or
-                ks_meta_vars['SWAP_SIZE_MB'] != str(self.cfg.swap_size_mb)):
-            LOG.debug(_('Profile ks_meta {!r} is not ok.').format('SWAP_SIZE_MB'))
-            ks_meta_ok = False
-        if ('SYSTEM_STATUS' not in ks_meta_vars or
-                ks_meta_vars['SYSTEM_STATUS'] != status):
-            LOG.debug(_('Profile ks_meta {!r} is not ok.').format('SYSTEM_STATUS'))
-            ks_meta_ok = False
-        if ('WS_REL_FILESDIR' not in ks_meta_vars or
-                ks_meta_vars['WS_REL_FILESDIR'] != str(self.cfg.cobbler_ws_rel_filesdir)):
-            LOG.debug(_('Profile ks_meta {!r} is not ok.').format('WS_REL_FILESDIR'))
-            ks_meta_ok = False
-        if ('COBBLER_URL' not in ks_meta_vars or
-                ks_meta_vars['COBBLER_URL'] != "http://{}".format(self.cfg.cobbler_host)):
-            LOG.debug(_('Profile ks_meta {!r} is not ok.').format('COBBLER_URL'))
-            ks_meta_ok = False
-
-        if not ks_meta_ok:
-            ks_meta_list = []
-            ks_meta_list.append("ROOT_PWD_HASH={}".format(self.cfg.get_root_pwd_hash()))
-            ks_meta_list.append("SWAP_SIZE_MB={}".format(self.cfg.swap_size_mb))
-            ks_meta_list.append("SYSTEM_STATUS={}".format(status))
-            ks_meta_list.append("WS_REL_FILESDIR={}".format(self.cfg.cobbler_ws_rel_filesdir))
-            ks_meta_list.append("COBBLER_URL=http://{}".format(self.cfg.cobbler_host))
-
-            ks_meta = ' '.join(ks_meta_list)
-
-            args.append('--autoinstall-meta')
-            args.append(ks_meta)
-
-        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
-
-        if self.verbose > 1:
-            LOG.debug('Arguments for changing profile:\n' + pp(args))
-        return
-
-        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 xform_ks_meta(self, ks_meta):
 
@@ -510,106 +259,6 @@ class Cobbler(BaseHandler, CobblerDistro, CobblerFiles):
 
         return data
 
-    # -------------------------------------------------------------------------
-    def add_profile(self):
-        """Creating a new profile."""
-
-        profile = self.cfg.cobbler_profile
-
-        LOG.info(_("Creating new profile {!r} ...").format(profile))
-
-        distro_info = self.cfg.current_distro
-        comment = "Profile for creating a {} VM.".format(distro_info.description)
-        status = self.cfg.system_status
-
-        LOG.debug("Using kickstart file {!r}".format(self.cfg.cobbler_profile_ks))
-
-        ks_meta_list = []
-        ks_meta_list.append("ROOT_PWD_HASH={}".format(self.cfg.get_root_pwd_hash()))
-        ks_meta_list.append("SWAP_SIZE_MB={}".format(self.cfg.swap_size_mb))
-        ks_meta_list.append("SYSTEM_STATUS={}".format(status))
-        ks_meta_list.append("WS_REL_FILESDIR={}".format(self.cfg.cobbler_ws_rel_filesdir))
-        ks_meta_list.append("COBBLER_URL=http://{}".format(self.cfg.cobbler_host))
-
-        ks_meta = None
-        if ks_meta_list:
-            ks_meta = ' '.join(ks_meta_list)
-
-        repos = []
-        if distro_info.repos:
-            repos = distro_info.repos.as_list()
-
-        args = ['profile', 'add']
-        args.append('--name')
-        args.append(self.cfg.cobbler_profile)
-        args.append('--distro')
-        args.append(distro_info.distro)
-        args.append('--enable-menu')
-        args.append('1')
-        if self.cfg.cobbler_major_version == 3:
-            args.append('--autoinstall')
-            args.append(str(self.cfg.cobbler_profile_ks.name))
-        else:
-            args.append('--kickstart')
-            args.append(str(self.cfg.cobbler_profile_ks))
-        if repos:
-            args.append('--repos')
-            args.append(' '.join(repos))
-        args.append('--comment')
-        args.append(comment)
-        if ks_meta:
-            if self.cfg.cobbler_major_version == 3:
-                args.append('--autoinstall-meta')
-            else:
-                args.append('--ksmeta')
-            args.append(ks_meta)
-        args.append('--virt-cpus')
-        args.append('2')
-        args.append('--virt-file-size')
-        args.append('20')
-        args.append('--virt-ram')
-        args.append('4096')
-        args.append('--virt-type')
-        args.append('vmware')
-        args.append('--virt-bridge')
-        args.append('br0')
-        args.append('--virt-disk-driver')
-        args.append('vmdk')
-        args.append('--name-servers')
-        args.append(' '.join(self.cfg.cobbler_nameservers))
-        args.append('--name-servers-search')
-        args.append(' '.join(self.cfg.cobbler_dns_search))
-
-        proc = self.exec_cobbler(args)
-
-        if self.verbose > 1:
-            LOG.debug(_("Completed SSH process:") + "\n{}".format(proc))
-
-        if proc.returncode:
-            err = _('No error message')
-            if proc.stderr:
-                err = proc.stderr
-            elif proc.stdout:
-                err = proc.stdout
-            msg = _("Error creating a cobbler profile - returncode was {rc}: {err}").format(
-                rc=proc.returncode, err=err)
-            raise ExpectedCobblerError(msg)
-
-        if proc.stderr:
-            msg = _("There was an error message on creating profile {!r}:").format(
-                self.cfg.cobbler_profile)
-            msg += ' ' + proc.stderr
-            LOG.error(msg)
-
-        if self.simulate:
-            return
-
-        profile_list = self.get_profile_list()
-        if self.cfg.cobbler_profile not in profile_list:
-            msg = _("Did not found profile {!r} after trying creation.").format(
-                self.cfg.cobbler_profile)
-            raise ExpectedCobblerError(msg)
-
     # -------------------------------------------------------------------------
     def ensure_system_ks(self):
 
diff --git a/lib/cr_vmware_tpl/cobbler/profile.py b/lib/cr_vmware_tpl/cobbler/profile.py
new file mode 100644 (file)
index 0000000..7a85f0d
--- /dev/null
@@ -0,0 +1,404 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+@author: Frank Brehm
+@contact: frank.brehm@pixelpark.com
+@copyright: © 2023 by Frank Brehm, Berlin
+@summary: A mixin module for the Cobbler class for profile dependend methods.
+"""
+from __future__ import absolute_import, print_function
+
+# Standard modules
+import logging
+import os
+import tempfile
+
+from pathlib import Path
+
+# Third party modules
+import jinja2
+
+from six.moves import configparser
+
+from fb_tools.common import pp, to_str, is_sequence, to_bool
+from fb_tools.xlate import format_list
+
+# Own modules
+from .. import print_section_start, print_section_end
+from ..errors import CobblerError, ExpectedCobblerError
+from ..xlate import XLATOR
+
+__version__ = '0.1.0'
+
+LOG = logging.getLogger(__name__)
+
+_ = XLATOR.gettext
+ngettext = XLATOR.ngettext
+
+# =============================================================================
+class CobblerProfile():
+    """
+    A mixin class for extending the Cobbler class for profile dependend methods.
+    """
+
+    # -------------------------------------------------------------------------
+    def get_profile_list(self):
+        """Trying to get a list of all configured cobbler profiles."""
+
+        profile_list = []
+        proc = self.exec_cobbler(('profile', 'list'), no_simulate=True, show_output=False)
+        for line in proc.stdout.splitlines():
+            profile = line.strip()
+            if profile:
+                profile_list.append(profile)
+        profile_list.sort(key=str.lower)
+        if self.verbose > 1:
+            LOG.debug(_("Sorted list of found profiles:") + "\n{}".format(pp(profile_list)))
+        return profile_list
+
+    # -------------------------------------------------------------------------
+    def ensure_profile_ks(self):
+
+        ks_template_name = self.cfg.current_distro.ks_template
+
+        LOG.info(_("Using {!r} as a template for the kickstart file.").format(
+            './templates/' + ks_template_name))
+
+        prefix = 'tmp.' + self.cfg.cobbler_profile + '.'
+        (fh, tmp_ks) = tempfile.mkstemp(prefix=prefix, suffix='.ks', text=True)
+        os.close(fh)
+        self.local_ks_file = Path(tmp_ks)
+        LOG.debug(_("Using temporary kickstart file {!r}.").format(tmp_ks))
+
+        snippet_lst = []
+        for snippet in sorted(self.cfg.current_distro.snippets.values(), key=str.lower):
+            snippet_lst.append(snippet)
+
+        jinja_env = jinja2.Environment(
+            loader=jinja2.FileSystemLoader(str(self.base_dir / 'templates')),
+            autoescape=jinja2.select_autoescape(),
+        )
+        ks_template = jinja_env.get_template(ks_template_name)
+        ks_content = ks_template.render(
+            distro=self.cfg.current_distro, snippets=snippet_lst) + '\n\n'
+        if self.verbose > 1:
+            LOG.debug(_("Generated kickstart file content:") + '\n' + ks_content)
+
+        self.local_ks_file.write_text(ks_content)
+
+        remote_ks = self.cfg.cobbler_profile_ks
+        LOG.info(_("Ensuring currentness of profile kickstart script {!r}.").format(
+            str(remote_ks)))
+
+        self.ensure_remote_file(self.local_ks_file, remote_ks)
+
+        LOG.debug(_("Removing {!r} ...").format(str(self.local_ks_file)))
+        self.local_ks_file.unlink()
+        self.local_ks_file = None
+
+    # -------------------------------------------------------------------------
+    def ensure_profile(self):
+        """Ensure the existence and the correctnes of the given profile."""
+
+        profile = self.cfg.cobbler_profile
+
+        LOG.info(_("Ensuring profile {!r} ...").format(profile))
+        print_section_start(
+            'cobbler_ensure_profile', 'Ensuring profile.', collapsed=True)
+
+        profile_list = self.get_profile_list()
+
+        if profile in profile_list:
+            self.change_profile()
+        else:
+            self.add_profile()
+
+        print_section_end('cobbler_ensure_profile')
+
+    # -------------------------------------------------------------------------
+    def change_profile(self):
+        """Ensure correctnes of an existing profile."""
+
+        profile = self.cfg.cobbler_profile
+
+        LOG.debug(_("Checking existing profile {!r} ...").format(profile))
+
+        profile_vars = self.get_profile_vars(profile)
+
+        if self.verbose > 1:
+            LOG.debug(_("Got profile variables:") + '\n' + pp(profile_vars))
+        self._change_profile(profile_vars)
+
+    # -------------------------------------------------------------------------
+    def get_profile_vars(self, profile):
+
+        vars_out = '[main]\n'
+
+        kwargs = {
+            'allow_no_value': True,
+            'strict': False,
+        }
+
+        cmd = ('profile', 'dumpvars', '--name', profile)
+
+        proc = self.exec_cobbler(cmd, no_simulate=True, show_output=False)
+        vars_out += proc.stdout
+
+        parser = configparser.RawConfigParser(**kwargs)
+        try:
+            parser.read_string(vars_out)
+        except Exception as e:
+            msg = _("Got {what} on reading and parsing of profile {p!r}:").format(
+                what=e.__class__.__name__, p=profile)
+            msg += ' ' + str(e)
+            raise ExpectedCobblerError(msg)
+
+        data = {}
+
+        for (key, value) in parser.items('main'):
+            k = key.lower()
+            data[k] = value
+
+        return data
+
+    # -------------------------------------------------------------------------
+    def _change_profile(self, profile_vars):
+
+        profile = self.cfg.cobbler_profile
+        distro = self.cfg.cobbler_distro
+        distro_info = self.cfg.current_distro
+        status = self.cfg.system_status
+
+        LOG.debug(_("Checking existing profile {n!r} ({d}) ...").format(
+            n=profile, d=distro_info.description))
+
+        repos = []
+        if distro_info.repos:
+            repos = distro_info.repos.as_list()
+        repos_str = ' '.join(repos)
+
+        comment = "Profile for creating a {} VM.".format(distro_info.description)
+        name_servers = '[' + ', '.join(
+            map(lambda x: "'" + x + "'", self.cfg.cobbler_nameservers)) + ']'
+        dns_search = '[' + ', '.join(
+            map(lambda x: "'" + x + "'", self.cfg.cobbler_dns_search)) + ']'
+
+        args = []
+
+        if self.verbose > 1:
+            msg = _("Checking for distro:") + ' ' + distro
+            LOG.debug(msg)
+        if profile_vars['distro'] != distro:
+            args.append('--distro')
+            args.append(distro)
+
+        enable_menu = to_bool(profile_vars['enable_menu'])
+        if not enable_menu:
+            args.append('--enable-menu')
+            args.append('1')
+
+        if self.cfg.cobbler_major_version == 3:
+            if profile_vars['autoinstall'] != str(self.cfg.cobbler_profile_ks.name):
+                args.append('--autoinstall')
+                args.append(str(self.cfg.cobbler_profile_ks.name))
+        else:
+            if profile_vars['kickstart'] != str(self.cfg.cobbler_profile_ks):
+                args.append('--kickstart')
+                args.append(str(self.cfg.cobbler_profile_ks))
+
+        if self.verbose > 1:
+            msg = _("Checking for repos:") + ' ' + repos_str
+            LOG.debug(msg)
+        if profile_vars['repos'] != repos_str:
+            args.append('--repos')
+            args.append(repos_str)
+
+        if profile_vars['comment'] != comment:
+            args.append('--comment')
+            args.append(comment)
+
+        if self.verbose > 1:
+            msg = _("Checking for nameservers:") + ' ' + name_servers
+            LOG.debug(msg)
+        if profile_vars['name_servers'] != name_servers:
+            args.append('--name-servers')
+            args.append(' '.join(self.cfg.cobbler_nameservers))
+
+        if self.verbose > 1:
+            msg = _("Checking for DNS search domains:") + ' ' + dns_search
+            LOG.debug(msg)
+        if profile_vars['name_servers_search'] != dns_search:
+            args.append('--name-servers-search')
+            args.append(' '.join(self.cfg.cobbler_dns_search))
+
+        ks_meta_ok = True
+        ks_meta_vars = {}
+        if 'autoinstall_meta' in profile_vars:
+            ks_meta_vars = self.xform_ks_meta(profile_vars['autoinstall_meta'])
+        if 'ROOT_PWD_HASH' not in ks_meta_vars:
+            LOG.debug(_('Profile ks_meta {!r} is not ok.').format('ROOT_PWD_HASH'))
+            ks_meta_ok = False
+        if ('SWAP_SIZE_MB' not in ks_meta_vars or
+                ks_meta_vars['SWAP_SIZE_MB'] != str(self.cfg.swap_size_mb)):
+            LOG.debug(_('Profile ks_meta {!r} is not ok.').format('SWAP_SIZE_MB'))
+            ks_meta_ok = False
+        if ('SYSTEM_STATUS' not in ks_meta_vars or
+                ks_meta_vars['SYSTEM_STATUS'] != status):
+            LOG.debug(_('Profile ks_meta {!r} is not ok.').format('SYSTEM_STATUS'))
+            ks_meta_ok = False
+        if ('WS_REL_FILESDIR' not in ks_meta_vars or
+                ks_meta_vars['WS_REL_FILESDIR'] != str(self.cfg.cobbler_ws_rel_filesdir)):
+            LOG.debug(_('Profile ks_meta {!r} is not ok.').format('WS_REL_FILESDIR'))
+            ks_meta_ok = False
+        if ('COBBLER_URL' not in ks_meta_vars or
+                ks_meta_vars['COBBLER_URL'] != "http://{}".format(self.cfg.cobbler_host)):
+            LOG.debug(_('Profile ks_meta {!r} is not ok.').format('COBBLER_URL'))
+            ks_meta_ok = False
+
+        if not ks_meta_ok:
+            ks_meta_list = []
+            ks_meta_list.append("ROOT_PWD_HASH={}".format(self.cfg.get_root_pwd_hash()))
+            ks_meta_list.append("SWAP_SIZE_MB={}".format(self.cfg.swap_size_mb))
+            ks_meta_list.append("SYSTEM_STATUS={}".format(status))
+            ks_meta_list.append("WS_REL_FILESDIR={}".format(self.cfg.cobbler_ws_rel_filesdir))
+            ks_meta_list.append("COBBLER_URL=http://{}".format(self.cfg.cobbler_host))
+
+            ks_meta = ' '.join(ks_meta_list)
+
+            args.append('--autoinstall-meta')
+            args.append(ks_meta)
+
+        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
+
+        if self.verbose > 1:
+            LOG.debug('Arguments for changing profile:\n' + pp(args))
+        return
+
+        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):
+        """Creating a new profile."""
+
+        profile = self.cfg.cobbler_profile
+
+        LOG.info(_("Creating new profile {!r} ...").format(profile))
+
+        distro_info = self.cfg.current_distro
+        comment = "Profile for creating a {} VM.".format(distro_info.description)
+        status = self.cfg.system_status
+
+        LOG.debug("Using kickstart file {!r}".format(self.cfg.cobbler_profile_ks))
+
+        ks_meta_list = []
+        ks_meta_list.append("ROOT_PWD_HASH={}".format(self.cfg.get_root_pwd_hash()))
+        ks_meta_list.append("SWAP_SIZE_MB={}".format(self.cfg.swap_size_mb))
+        ks_meta_list.append("SYSTEM_STATUS={}".format(status))
+        ks_meta_list.append("WS_REL_FILESDIR={}".format(self.cfg.cobbler_ws_rel_filesdir))
+        ks_meta_list.append("COBBLER_URL=http://{}".format(self.cfg.cobbler_host))
+
+        ks_meta = None
+        if ks_meta_list:
+            ks_meta = ' '.join(ks_meta_list)
+
+        repos = []
+        if distro_info.repos:
+            repos = distro_info.repos.as_list()
+
+        args = ['profile', 'add']
+        args.append('--name')
+        args.append(self.cfg.cobbler_profile)
+        args.append('--distro')
+        args.append(distro_info.distro)
+        args.append('--enable-menu')
+        args.append('1')
+        if self.cfg.cobbler_major_version == 3:
+            args.append('--autoinstall')
+            args.append(str(self.cfg.cobbler_profile_ks.name))
+        else:
+            args.append('--kickstart')
+            args.append(str(self.cfg.cobbler_profile_ks))
+        if repos:
+            args.append('--repos')
+            args.append(' '.join(repos))
+        args.append('--comment')
+        args.append(comment)
+        if ks_meta:
+            if self.cfg.cobbler_major_version == 3:
+                args.append('--autoinstall-meta')
+            else:
+                args.append('--ksmeta')
+            args.append(ks_meta)
+        args.append('--virt-cpus')
+        args.append('2')
+        args.append('--virt-file-size')
+        args.append('20')
+        args.append('--virt-ram')
+        args.append('4096')
+        args.append('--virt-type')
+        args.append('vmware')
+        args.append('--virt-bridge')
+        args.append('br0')
+        args.append('--virt-disk-driver')
+        args.append('vmdk')
+        args.append('--name-servers')
+        args.append(' '.join(self.cfg.cobbler_nameservers))
+        args.append('--name-servers-search')
+        args.append(' '.join(self.cfg.cobbler_dns_search))
+
+        proc = self.exec_cobbler(args)
+
+        if self.verbose > 1:
+            LOG.debug(_("Completed SSH process:") + "\n{}".format(proc))
+
+        if proc.returncode:
+            err = _('No error message')
+            if proc.stderr:
+                err = proc.stderr
+            elif proc.stdout:
+                err = proc.stdout
+            msg = _("Error creating a cobbler profile - returncode was {rc}: {err}").format(
+                rc=proc.returncode, err=err)
+            raise ExpectedCobblerError(msg)
+
+        if proc.stderr:
+            msg = _("There was an error message on creating profile {!r}:").format(
+                self.cfg.cobbler_profile)
+            msg += ' ' + proc.stderr
+            LOG.error(msg)
+
+        if self.simulate:
+            return
+
+        profile_list = self.get_profile_list()
+        if self.cfg.cobbler_profile not in profile_list:
+            msg = _("Did not found profile {!r} after trying creation.").format(
+                self.cfg.cobbler_profile)
+            raise ExpectedCobblerError(msg)
+
+
+# =============================================================================
+if __name__ == "__main__":
+
+    pass
+
+# =============================================================================
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list