diff options
author | John Mulligan <jmulligan@redhat.com> | 2023-12-12 20:57:15 +0100 |
---|---|---|
committer | John Mulligan <jmulligan@redhat.com> | 2023-12-13 16:04:29 +0100 |
commit | 1950cc0ea764bb03f3598dc2c4576110d0d51d9d (patch) | |
tree | 0fbd2767e8902db8ac1e2f72620187cfd6ab63a6 /src/cephadm/build.py | |
parent | Merge pull request #53841 from pilem/bug62320 (diff) | |
download | ceph-1950cc0ea764bb03f3598dc2c4576110d0d51d9d.tar.xz ceph-1950cc0ea764bb03f3598dc2c4576110d0d51d9d.zip |
cephadm: add InstallSpec type to build.py
Add a new InstallSpec type to build.py and rework the requirements lists
in terms of the InstallSpec. The new type will be able to encode more
per-dependency behavior than the previous approach.
Signed-off-by: John Mulligan <jmulligan@redhat.com>
Diffstat (limited to 'src/cephadm/build.py')
-rwxr-xr-x | src/cephadm/build.py | 74 |
1 files changed, 53 insertions, 21 deletions
diff --git a/src/cephadm/build.py b/src/cephadm/build.py index 1634eeac593..54de52a1fa8 100755 --- a/src/cephadm/build.py +++ b/src/cephadm/build.py @@ -31,12 +31,18 @@ log = logging.getLogger(__name__) PY36_REQUIREMENTS = [ - 'MarkupSafe >= 2.0.1, <2.2', - 'Jinja2 >= 3.0.2, <3.2', + { + 'package_spec': 'MarkupSafe >= 2.0.1, <2.2', + 'unique': True, + }, + { + 'package_spec': 'Jinja2 >= 3.0.2, <3.2', + 'unique': True, + }, ] PY_REQUIREMENTS = [ - 'MarkupSafe >= 2.1.3, <2.2', - 'Jinja2 >= 3.1.2, <3.2', + {'package_spec': 'MarkupSafe >= 2.1.3, <2.2'}, + {'package_spec': 'Jinja2 >= 3.1.2, <3.2'}, ] # IMPORTANT to be fully compatible with all the distros ceph is built for we # need to work around various old versions of python/pip. As such it's easier @@ -53,6 +59,33 @@ _VALID_VERS_VARS = [ ] +class InstallSpec: + def __init__( + self, package_spec, custom_pip_args=None, unique=False, **kwargs + ): + self.package_spec = package_spec + self.name = package_spec.split()[0] + self.custom_pip_args = custom_pip_args or [] + self.unique = unique + self.extra = kwargs + + @property + def pip_args(self): + return self.custom_pip_args + + @property + def pip_args_and_package(self): + return self.pip_args + [self.package_spec] + + def compatible(self, other): + return ( + other + and not self.unique + and not other.unique + and self.pip_args == other.pip_args + ) + + class PipEnv(enum.Enum): never = enum.auto() auto = enum.auto() @@ -84,15 +117,13 @@ class Config: def _setup_pip(self): if self._maj_min == (3, 6): - self.pip_split = True - self.requirements = PY36_REQUIREMENTS + self.requirements = [InstallSpec(**v) for v in PY36_REQUIREMENTS] else: - self.pip_split = False - self.requirements = PY_REQUIREMENTS + self.requirements = [InstallSpec(**v) for v in PY_REQUIREMENTS] self.pip_venv = PipEnv[self.cli_args.pip_use_venv] def _setup_rpm(self): - self.requirements = [s.split()[0] for s in PY_REQUIREMENTS] + self.requirements = [InstallSpec(**v) for v in PY_REQUIREMENTS] class DependencyInfo: @@ -101,7 +132,7 @@ class DependencyInfo: def __init__(self, config): self._config = config self._deps = [] - self._reqs = {s.split()[0]: s for s in self._config.requirements} + self._reqs = {s.name: s.package_spec for s in self._config.requirements} @property def requirements(self): @@ -259,15 +290,16 @@ def _install_pip_deps(tempdir, config): env['PYTHONPATH'] = env['PYTHONPATH'] + f':{tempdir}' else: env['PYTHONPATH'] = f'{tempdir}' - if config.pip_split: - # a list of single item lists; so that pip run once for each - # requirement - req_batches = [[r] for r in config.requirements] - else: - # a list containing another list of the requirements, so we only - # need to run pip once - req_batches = [list(config.requirements)] - for batch in req_batches: + + pip_args = [] + prev = None + for ispec in config.requirements: + if ispec.compatible(prev) and pip_args: + pip_args[0].append(ispec.package_spec) + else: + pip_args.append(ispec.pip_args_and_package) + prev = ispec + for batch in pip_args: _run( [ executable, @@ -321,8 +353,8 @@ def _install_rpm_deps(tempdir, config): log.info("Installing dependencies using RPMs") dinfo = DependencyInfo(config) for pkg in config.requirements: - log.info(f"Looking for rpm package for: {pkg!r}") - _deps_from_rpm(tempdir, config, dinfo, pkg) + log.info(f"Looking for rpm package for: {pkg.name!r}") + _deps_from_rpm(tempdir, config, dinfo, pkg.name) return dinfo |