From: Frank Brehm Date: Thu, 23 Jun 2022 10:51:05 +0000 (+0200) Subject: Adding class CobblerDistroInfo to module cr_vmware_tpl.config. X-Git-Tag: 2.6.2~1^2~8^2~48 X-Git-Url: https://git.uhu-banane.org/?a=commitdiff_plain;h=a129b3b44a701632e41891a85218ee2ee1690220;p=pixelpark%2Fcreate-vmware-tpl.git Adding class CobblerDistroInfo to module cr_vmware_tpl.config. --- diff --git a/lib/cr_vmware_tpl/config.py b/lib/cr_vmware_tpl/config.py index a979ac5..1a66e2d 100644 --- a/lib/cr_vmware_tpl/config.py +++ b/lib/cr_vmware_tpl/config.py @@ -19,6 +19,8 @@ from pathlib import Path # 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 @@ -29,7 +31,7 @@ from . import DEFAULT_CONFIG_DIR from .xlate import XLATOR -__version__ = '1.8.1' +__version__ = '1.9.1' LOG = logging.getLogger(__name__) _ = XLATOR.gettext @@ -44,6 +46,222 @@ class CrTplConfigError(MultiConfigError): 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): """ @@ -334,6 +552,11 @@ 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: @@ -379,27 +602,27 @@ class CrTplConfiguration(BaseMultiConfig): 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)) @@ -751,40 +974,9 @@ class CrTplConfiguration(BaseMultiConfig): 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'):