"""
@author: Frank Brehm
@contact: frank.brehm@pixelpark.com
-@copyright: © 2018 by Frank Brehm, Berlin
+@copyright: © 2023 by Frank Brehm, Berlin
@summary: A module for providing a configuration
"""
from __future__ import absolute_import
# Third party modules
from pathlib import Path
-from fb_tools.common import is_sequence, pp, to_bool
-from fb_tools.obj import FbGenericBaseObject
-from fb_tools.collections import CIStringSet
+from fb_tools.common import is_sequence, pp
from fb_tools.multi_config import BaseMultiConfig
from fb_tools.multi_config import DEFAULT_ENCODING
from fb_tools.xlate import format_list
from fb_vmware.config import VSPhereConfigInfo
# Own modules
-from .. import DEFAULT_CONFIG_DIR, DEFAULT_DISTRO_ARCH
+from .. import DEFAULT_CONFIG_DIR
from .. import DEFAULT_PORT_LDAPS, DEFAULT_TIMEOUT, MAX_TIMEOUT
from ..errors import CrTplConfigError
from ..xlate import XLATOR
+from .distro import CobblerDistroInfo
from .ldap import LdapConnectionInfo, LdapConnectionDict
-__version__ = '3.0.1'
+__version__ = '3.0.2'
LOG = logging.getLogger(__name__)
_ = XLATOR.gettext
ngettext = XLATOR.ngettext
-# =============================================================================
-class CobblerDistroInfo(FbGenericBaseObject):
- """Class for encapsulation all necessary data of a Repo definition in Cobbler."""
-
- re_dashes = re.compile(r'[_-]')
- valid_arch = (
- 'i386', 'x86_64', 'ia64', 'ppc', 'ppc64', 'ppc64el', 'ppc64le',
- 's390', 's390x', 'arm', 'aarch64')
-
- # -------------------------------------------------------------------------
- def __init__(
- self, name, shortname=None, distro=None, description=None, arch=DEFAULT_DISTRO_ARCH,
- ks_repo_url=None, packages=None, repos=None, snippets=None):
-
- self._name = None
- self._shortname = None
- self._distro = None
- self._description = None
- self._arch = DEFAULT_DISTRO_ARCH
- self._ks_repo_url = None
- self._is_rhel = False
- self._ks_template = 'el8-standard.ks'
- self.packages = []
- self.repos = CIStringSet()
- self.snippets = CIStringSet()
-
- self.name = name
- self.shortname = shortname
- self.distro = distro
- self.description = description
- self.arch = arch
-
- if packages:
- if is_sequence(packages):
- for pkg in packages:
- if pkg not in packages:
- self.packages.append(pkg)
- else:
- msg = _("The given parameter {p!r} must be sequential type (given: {v!r}).")
- raise TypeError(msg.format(p='packages', v=repos))
-
- if repos:
- if is_sequence(repos):
- for repo in repos:
- self.repos.add(repo)
- 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)
- for snippet in snippets:
- self.snippets.add(snippet)
- 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 arch(self):
- """The name of the underlaying (real) cobbler distro."""
- return getattr(self, '_arch', DEFAULT_DISTRO_ARCH)
-
- @arch.setter
- def arch(self, value):
-
- arch = value.strip().lower()
- if arch not in self.valid_arch:
- msg = _(
- "Invalid architecture {a!r} for distro {n!r} given. Valid architectures are {v}.")
- msg = msg.format(a=value, n=self.name, v=format_list(self.valid_arch, do_repr=True))
- raise ValueError(msg)
-
- self._arch = arch
-
- # -------------------------------------------------------------------------
- @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
-
- # -------------------------------------------------------------------------
- @property
- def ks_repo_url(self):
- """The URL for the base installation repository."""
- return getattr(self, '_ks_repo_url', None)
-
- @ks_repo_url.setter
- def ks_repo_url(self, value):
- if value is None:
- self._ks_repo_url = None
- return
-
- ks_repo_url = value.strip()
- if ks_repo_url == '':
- self._ks_repo_url = None
- return
-
- self._ks_repo_url = ks_repo_url
-
- # -------------------------------------------------------------------------
- @property
- def is_rhel(self):
- """Is the currwnt distro a RHEL distro?"""
- return self._is_rhel
-
- @is_rhel.setter
- def is_rhel(self, value):
- self._is_rhel = to_bool(value)
-
- # -------------------------------------------------------------------------
- @property
- def ks_template(self):
- """The filename below templates for generating the final kickstart file."""
-
- return getattr(self, '_ks_template', 'el8-standard.ks')
-
- @ks_template.setter
- def ks_template(self, value):
- if value is None:
- return
- template = value.strip()
- if template == '':
- return
- self._ks_template = template
-
- # -------------------------------------------------------------------------
- @property
- def repos_string(self):
- """Returns all repos as a string of their space concatinated names."""
- if self.repos:
- return ' '.join(self.repos.as_list())
- return ''
-
- # -------------------------------------------------------------------------
- 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("arch={!r}".format(self.arch))
- fields.append("is_rhel={!r}".format(self.is_rhel))
- fields.append("ks_template={!r}".format(self.ks_template))
- fields.append("description={!r}".format(self.description))
- fields.append("ks_repo_url={!r}".format(self.ks_repo_url))
-
- 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['arch'] = self.arch
- res['description'] = self.description
- res['distro'] = self.distro
- res['is_rhel'] = self.is_rhel
- res['ks_repo_url'] = self.ks_repo_url
- res['ks_template'] = self.ks_template
- res['name'] = self.name
- res['repos_string'] = self.repos_string
- res['shortname'] = self.shortname
-
- return res
-
- # -------------------------------------------------------------------------
- def __eq__(self, other):
-
- if not isinstance(other, CobblerDistroInfo):
- return False
-
- return self.name == other.name
-
- # -------------------------------------------------------------------------
- def __copy__(self):
-
- new = self.__class__(
- self.name, shortname=self.shortname, distro=self.distro, arch=self.arch,
- ks_repo_url=self.ks_repo_url, description=self.description)
-
- for package in self.packages:
- new.packages.append(package)
-
- 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.strip()
- continue
-
- if key.lower() == 'distro' and value.strip() != '':
- new.distro = value.strip()
- continue
-
- if key.lower() == 'description' and value.strip() != '':
- new.description = value.strip()
- continue
-
- if key.lower() == 'arch' and value.strip() != '':
- new.arch = value.strip()
- continue
-
- if key.lower() == 'is_rhel':
- new.is_rhel = value
- continue
-
- if key.lower() == 'ks_repo_url' and value.strip() != '':
- new.ks_repo_url = value.strip()
- continue
-
- if key.lower() == 'ks_template' and value.strip() != '':
- new._ks_template = value.strip()
- continue
-
- if key.lower() == 'repos':
- cls._update_repos(new, value)
- continue
-
- if key.lower() == 'packages':
- cls._update_packages(new, value)
- continue
-
- if key.lower() == 'snippets':
- cls._update_snippets(new, value)
- 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))
-
- if verbose > 2:
- msg = _("Found Cobbler repository configuration:") + '\n' + pp(new.as_dict())
- LOG.debug(msg)
-
- return new
-
- # -------------------------------------------------------------------------
- @classmethod
- def _update_repos(cls, new, value):
-
- 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())
-
- # -------------------------------------------------------------------------
- @classmethod
- def _update_packages(cls, new, value):
-
- if is_sequence(value):
- for pkg in value:
- pkg = pkg.strip()
- if pkg != '' and pkg not in new.packages:
- new.packages.append(pkg)
- elif value.strip() != '':
- new.packages.add(value.strip())
-
- # -------------------------------------------------------------------------
- @classmethod
- def _update_snippets(cls, new, value):
-
- 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())
-
-
# =============================================================================
class CrTplConfiguration(BaseMultiConfig):
"""
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+@author: Frank Brehm
+@contact: frank.brehm@pixelpark.com
+@copyright: © 20123by Frank Brehm, Berlin
+@summary: A module for providing a configuration for cobbler distros
+"""
+from __future__ import absolute_import
+
+# Standard module
+import logging
+import re
+import copy
+
+# Third party modules
+from fb_tools.common import is_sequence, pp, to_bool
+from fb_tools.obj import FbGenericBaseObject
+from fb_tools.collections import CIStringSet
+from fb_tools.xlate import format_list
+
+# Own modules
+from .. import DEFAULT_DISTRO_ARCH
+
+from ..xlate import XLATOR
+
+__version__ = '0.1.0'
+LOG = logging.getLogger(__name__)
+
+_ = XLATOR.gettext
+ngettext = XLATOR.ngettext
+
+
+# =============================================================================
+class CobblerDistroInfo(FbGenericBaseObject):
+ """Class for encapsulation all necessary data of a Repo definition in Cobbler."""
+
+ re_dashes = re.compile(r'[_-]')
+ valid_arch = (
+ 'i386', 'x86_64', 'ia64', 'ppc', 'ppc64', 'ppc64el', 'ppc64le',
+ 's390', 's390x', 'arm', 'aarch64')
+
+ # -------------------------------------------------------------------------
+ def __init__(
+ self, name, shortname=None, distro=None, description=None, arch=DEFAULT_DISTRO_ARCH,
+ ks_repo_url=None, packages=None, repos=None, snippets=None):
+
+ self._name = None
+ self._shortname = None
+ self._distro = None
+ self._description = None
+ self._arch = DEFAULT_DISTRO_ARCH
+ self._ks_repo_url = None
+ self._is_rhel = False
+ self._ks_template = 'el8-standard.ks'
+ self.packages = []
+ self.repos = CIStringSet()
+ self.snippets = CIStringSet()
+
+ self.name = name
+ self.shortname = shortname
+ self.distro = distro
+ self.description = description
+ self.arch = arch
+
+ if packages:
+ if is_sequence(packages):
+ for pkg in packages:
+ if pkg not in packages:
+ self.packages.append(pkg)
+ else:
+ msg = _("The given parameter {p!r} must be sequential type (given: {v!r}).")
+ raise TypeError(msg.format(p='packages', v=repos))
+
+ if repos:
+ if is_sequence(repos):
+ for repo in repos:
+ self.repos.add(repo)
+ 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)
+ for snippet in snippets:
+ self.snippets.add(snippet)
+ 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 arch(self):
+ """The name of the underlaying (real) cobbler distro."""
+ return getattr(self, '_arch', DEFAULT_DISTRO_ARCH)
+
+ @arch.setter
+ def arch(self, value):
+
+ arch = value.strip().lower()
+ if arch not in self.valid_arch:
+ msg = _(
+ "Invalid architecture {a!r} for distro {n!r} given. Valid architectures are {v}.")
+ msg = msg.format(a=value, n=self.name, v=format_list(self.valid_arch, do_repr=True))
+ raise ValueError(msg)
+
+ self._arch = arch
+
+ # -------------------------------------------------------------------------
+ @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
+
+ # -------------------------------------------------------------------------
+ @property
+ def ks_repo_url(self):
+ """The URL for the base installation repository."""
+ return getattr(self, '_ks_repo_url', None)
+
+ @ks_repo_url.setter
+ def ks_repo_url(self, value):
+ if value is None:
+ self._ks_repo_url = None
+ return
+
+ ks_repo_url = value.strip()
+ if ks_repo_url == '':
+ self._ks_repo_url = None
+ return
+
+ self._ks_repo_url = ks_repo_url
+
+ # -------------------------------------------------------------------------
+ @property
+ def is_rhel(self):
+ """Is the currwnt distro a RHEL distro?"""
+ return self._is_rhel
+
+ @is_rhel.setter
+ def is_rhel(self, value):
+ self._is_rhel = to_bool(value)
+
+ # -------------------------------------------------------------------------
+ @property
+ def ks_template(self):
+ """The filename below templates for generating the final kickstart file."""
+
+ return getattr(self, '_ks_template', 'el8-standard.ks')
+
+ @ks_template.setter
+ def ks_template(self, value):
+ if value is None:
+ return
+ template = value.strip()
+ if template == '':
+ return
+ self._ks_template = template
+
+ # -------------------------------------------------------------------------
+ @property
+ def repos_string(self):
+ """Returns all repos as a string of their space concatinated names."""
+ if self.repos:
+ return ' '.join(self.repos.as_list())
+ return ''
+
+ # -------------------------------------------------------------------------
+ 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("arch={!r}".format(self.arch))
+ fields.append("is_rhel={!r}".format(self.is_rhel))
+ fields.append("ks_template={!r}".format(self.ks_template))
+ fields.append("description={!r}".format(self.description))
+ fields.append("ks_repo_url={!r}".format(self.ks_repo_url))
+
+ 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['arch'] = self.arch
+ res['description'] = self.description
+ res['distro'] = self.distro
+ res['is_rhel'] = self.is_rhel
+ res['ks_repo_url'] = self.ks_repo_url
+ res['ks_template'] = self.ks_template
+ res['name'] = self.name
+ res['repos_string'] = self.repos_string
+ res['shortname'] = self.shortname
+
+ return res
+
+ # -------------------------------------------------------------------------
+ def __eq__(self, other):
+
+ if not isinstance(other, CobblerDistroInfo):
+ return False
+
+ return self.name == other.name
+
+ # -------------------------------------------------------------------------
+ def __copy__(self):
+
+ new = self.__class__(
+ self.name, shortname=self.shortname, distro=self.distro, arch=self.arch,
+ ks_repo_url=self.ks_repo_url, description=self.description)
+
+ for package in self.packages:
+ new.packages.append(package)
+
+ 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.strip()
+ continue
+
+ if key.lower() == 'distro' and value.strip() != '':
+ new.distro = value.strip()
+ continue
+
+ if key.lower() == 'description' and value.strip() != '':
+ new.description = value.strip()
+ continue
+
+ if key.lower() == 'arch' and value.strip() != '':
+ new.arch = value.strip()
+ continue
+
+ if key.lower() == 'is_rhel':
+ new.is_rhel = value
+ continue
+
+ if key.lower() == 'ks_repo_url' and value.strip() != '':
+ new.ks_repo_url = value.strip()
+ continue
+
+ if key.lower() == 'ks_template' and value.strip() != '':
+ new._ks_template = value.strip()
+ continue
+
+ if key.lower() == 'repos':
+ cls._update_repos(new, value)
+ continue
+
+ if key.lower() == 'packages':
+ cls._update_packages(new, value)
+ continue
+
+ if key.lower() == 'snippets':
+ cls._update_snippets(new, value)
+ 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))
+
+ if verbose > 2:
+ msg = _("Found Cobbler repository configuration:") + '\n' + pp(new.as_dict())
+ LOG.debug(msg)
+
+ return new
+
+ # -------------------------------------------------------------------------
+ @classmethod
+ def _update_repos(cls, new, value):
+
+ 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())
+
+ # -------------------------------------------------------------------------
+ @classmethod
+ def _update_packages(cls, new, value):
+
+ if is_sequence(value):
+ for pkg in value:
+ pkg = pkg.strip()
+ if pkg != '' and pkg not in new.packages:
+ new.packages.append(pkg)
+ elif value.strip() != '':
+ new.packages.add(value.strip())
+
+ # -------------------------------------------------------------------------
+ @classmethod
+ def _update_snippets(cls, new, value):
+
+ 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())
+
+
+# =============================================================================
+if __name__ == "__main__":
+
+ pass
+
+# =============================================================================
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list