# Own modules
from fb_tools.common import is_sequence
+from fb_tools.obj import FbGenericBaseObject
+from fb_tools.collections import CIStringSet
from fb_tools.multi_config import MultiConfigError, BaseMultiConfig
from fb_tools.multi_config import DEFAULT_ENCODING
from fb_tools.xlate import format_list
from .xlate import XLATOR
-__version__ = '1.8.1'
+__version__ = '1.9.1'
LOG = logging.getLogger(__name__)
_ = XLATOR.gettext
pass
+# =============================================================================
+class CobblerDistroInfo(FbGenericBaseObject):
+ """Class for encapsulation all necessary data of a Repo definition in Cobbler."""
+
+ re_dashes = re.compile(r'[_-]')
+
+ # -------------------------------------------------------------------------
+ def __init__(
+ self, name, shortname=None, distro=None, description=None, repos=None, snippets=None):
+
+ self._name = None
+ self._shortname = None
+ self._distro = None
+ self._description = None
+ self.repos = CIStringSet()
+ self.snippets = CIStringSet()
+
+ self.name = name
+ self.shortname = shortname
+ self.distro = distro
+ self.description = description
+
+ if repos:
+ if is_sequence(repos):
+ self.repos = copy.copy(repos)
+ else:
+ msg = _("The given parameter {p!r} must be sequential type (given: {v!r}).")
+ raise TypeError(msg.format(p='repos', v=repos))
+
+ if snippets:
+ if is_sequence(repos):
+ self.snippets = copy.copy(snippets)
+ else:
+ msg = _("The given parameter {p!r} must be sequential type (given: {v!r}).")
+ raise TypeError(msg.format(p='snippets', v=snippets))
+
+ # -------------------------------------------------------------------------
+ @property
+ def name(self):
+ """The canonical name of the distribution."""
+ return getattr(self, '_name', None)
+
+ @name.setter
+ def name(self, value):
+
+ name = value.strip()
+ if name == '':
+ msg = _("The name of a Cobbler distro may not be empty.")
+ raise ValueError(msg)
+
+ self._name = name
+
+ # -------------------------------------------------------------------------
+ @property
+ def shortname(self):
+ """The short name of the distro, how to be used e.g. as part of the template name."""
+
+ shortname = getattr(self, '_shortname', None)
+ if shortname is None:
+ name = self.name
+ if name is None:
+ return None
+ shortname = self.re_dashes.sub('', name)
+ return shortname
+
+ @shortname.setter
+ def shortname(self, value):
+ if value is None:
+ self._shortname = None
+ return
+ shortname = value.strip()
+ if shortname == '':
+ self._shortname = None
+ return
+ self._shortname = shortname
+
+ # -------------------------------------------------------------------------
+ @property
+ def distro(self):
+ """The name of the underlaying (real) cobbler distro."""
+ return getattr(self, '_distro', None)
+
+ @distro.setter
+ def distro(self, value):
+ if value is None:
+ self._distro = None
+ return
+
+ dis = value.strip()
+ if dis == '':
+ self._distro = None
+ return
+
+ self._distro = dis
+
+ # -------------------------------------------------------------------------
+ @property
+ def description(self):
+ """The name of the underlaying (real) cobbler distro."""
+ return getattr(self, '_description', None)
+
+ @description.setter
+ def description(self, value):
+ if value is None:
+ self._description = None
+ return
+
+ desc = value.strip()
+ if desc == '':
+ self._description = None
+ return
+
+ self._description = desc
+
+ # -------------------------------------------------------------------------
+ def __repr__(self):
+ """Typecasting into a string for reproduction."""
+
+ out = "<%s()" % (self.__class__.__name__)
+
+ fields = []
+ fields.append("name={!r}".format(self.name))
+ fields.append("shortname={!r}".format(self._shortname))
+ fields.append("distro={!r}".format(self.distro))
+ fields.append("description={!r}".format(self.description))
+
+ out += ", ".join(fields) + ")>"
+
+
+ return out
+
+ # -------------------------------------------------------------------------
+ def as_dict(self, short=True):
+ """
+ Transforms the elements of the object into a dict
+
+ @param short: don't include local properties in resulting dict.
+ @type short: bool
+
+ @return: structure as dict
+ @rtype: dict
+ """
+
+ res = super(CobblerDistroInfo, self).as_dict(short=short)
+ res['name'] = self.name
+ res['shortname'] = self.shortname
+ res['distro'] = self.distro
+ res['description'] = self.description
+
+ return res
+
+ # -------------------------------------------------------------------------
+ def __copy__(self):
+
+ new = self.__class__(
+ self.name, shortname=self.shortname, distro=self.distro, description=self.description)
+
+ for repo in self.repos:
+ new.repos.add(repo)
+
+ for snippet in self.snippets:
+ new.snippets.add(snippet)
+
+ return new
+
+ # -------------------------------------------------------------------------
+ @classmethod
+ def init_from_config(cls, name, data, verbose=0):
+
+ new = cls(name)
+
+ for key in data.keys():
+ value = data[key]
+
+ if key.lower() == 'shortname' and value.strip() != '':
+ new.shortname = value
+ continue
+
+ if key.lower() == 'distro' and value.strip() != '':
+ new.distro = value
+ continue
+
+ if key.lower() == 'description' and value.strip() != '':
+ new.description = value
+ continue
+
+ if key.lower() == 'repos':
+ if is_sequence(value):
+ for repo in value:
+ repo = repo.strip()
+ if repo != '':
+ new.repos.add(repo)
+ elif value.strip() != '':
+ new.repos.add(value.strip())
+
+ continue
+
+ if key.lower() == 'snippets':
+ if is_sequence(value):
+ for snippet in value:
+ snippet = snippet.strip()
+ if snippet != '':
+ new.snippets.add(snippet)
+ elif value.strip() != '':
+ new.snippets.add(value.strip())
+
+ continue
+
+ if verbose:
+ LOG.warn(_(
+ "Found unknown config parameter {p!r} with value {v!r} in configuration "
+ "of the Cobbler repository {r!r}.").format(p=key, v=value, r=name))
+
+ return new
+
+
# =============================================================================
class CrTplConfiguration(BaseMultiConfig):
"""
res['system_ks'] = self.system_ks
res['snippets_dir'] = self.snippets_dir
+ res['cobbler_distros'] = {}
+ for distro in self.cobbler_distros.keys():
+ res['cobbler_distros'][distro] = self.cobbler_distros[distro].as_dict(short=short)
+
+
res['root_password'] = None
if self.root_password:
if self.verbose > 4:
raise CrTplConfigError(msg)
for distro_id in self.cobbler_distros.keys():
- distro_info = self.cobbler_distros[distro_id]
+ distro = self.cobbler_distros[distro_id]
- if 'distro' not in distro_info:
+ if not distro.distro:
msg = _("Did not found distro of configured Cobbler distro {!r}.").format(
distro_id)
raise CrTplConfigError(msg)
- if not len(distro_info['repos']):
+ if not len(distro.repos):
msg = _(
"Did not found repo definitions for configured Cobbler "
"distro {!r}.").format(distro_id)
LOG.warn(msg)
- if 'description' not in distro_info:
- distro_info['description'] = distro_id
+ if not distro.description:
+ distro.description = distro_id
if self.os_id not in self.cobbler_distros:
msg = _("Did not found distro {!r} in configured Cobbler distros.").format(self.os_id)
raise CrTplConfigError(msg)
- self.cobbler_distro = self.cobbler_distros[self.os_id]['distro']
+ self.cobbler_distro = self.cobbler_distros[self.os_id].distro
LOG.info(_("Using OS {os!r} with cobbler distro {di!r}.").format(
os=self.os_id, di=self.cobbler_distro))
for distro_id in section.keys():
distro_info = section[distro_id]
distro_id = distro_id.lower()
- if distro_id not in self.cobbler_distros:
- self.cobbler_distros[distro_id] = {}
-
- self._eval_cobbler_distro(distro_id, distro_info)
-
- # -------------------------------------------------------------------------
- def _eval_cobbler_distro(self, distro_id, distro_info):
-
- if self.verbose > 2:
- LOG.debug(_("Evaluating Cobbler distro {!r} ...").format(distro_id))
-
- distro = self.cobbler_distros[distro_id]
-
- if 'repos' not in distro:
- distro['repos'] = []
-
- for key in distro_info.keys():
- value = distro_info[key]
-
- if key.lower() == 'distro' and value.strip() != '':
- distro['distro'] = value.strip()
- continue
- if key.lower() == 'description' and value.strip() != '':
- distro['description'] = value.strip()
- continue
- if key.lower() == 'repos':
- if is_sequence(value):
- for repo in value:
- repo = repo.strip()
- if repo != '':
- distro['repos'].append(repo)
- elif value.strip() != '':
- distro['repos'].append(value.strip())
- continue
+ distro = CobblerDistroInfo.init_from_config(
+ distro_id, distro_info, verbose=self.verbose)
+ self.cobbler_distros[distro_id] = distro
# -------------------------------------------------------------------------
def get_root_pwd_hash(self, method='sha256'):