From a2abf0dba92806cc737d57aadf9e852bf25ada8b Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Tue, 11 Dec 2018 20:19:08 +0800 Subject: [PATCH] task/install: add "downgrade_packages" option for "install" task in rados/thrash-old-clients, hammer or jewel packages is installed. but yum does not allow downgrade a package by default, if a newer version is already installed. in this case, librbd1 and librados2 are installed as dependencies of qemu-kvm. their version is 1:10.2.5-4.el7 at the time of writing in CentOS/RHEL 7.5. so if we want to install librbd1 or librados2 from jewel, yum will simply consider the requirement is already fulfilled and hence do nothing. if we want to install ceph-radosgw from jewel, yum will fail, as ceph-radosgw depends on librados2 and other Ceph packages of the same version from jewel. but librbd1 and librados2 have been already installed. the error message looks like: Error: Package: 1:ceph-common-0.94.10-87.g116a558.el7.x86_64 (Ceph) Requires: librados2 = 1:0.94.10-87.g116a558.el7 Installed: 1:librados2-10.2.5-4.el7.x86_64 (@base) librados2 = 1:10.2.5-4.el7 Available: 1:librados2-0.94.10-87.g116a558.el7.x86_64 (Ceph) librados2 = 1:0.94.10-87.g116a558.el7 so we need to downgrade librbd1 and librados2 first. in this change, "downgrade_package" option is added for "install" task, so we can specify packages to be downgraded to given version, these packages won't be installed twice if they are also specified by "install" task elsewhere to be installed. Signed-off-by: Kefu Chai --- teuthology/task/install/__init__.py | 11 +++++++++ teuthology/task/install/rpm.py | 37 +++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/teuthology/task/install/__init__.py b/teuthology/task/install/__init__.py index 43b06c7b9..11e58f7ee 100644 --- a/teuthology/task/install/__init__.py +++ b/teuthology/task/install/__init__.py @@ -547,6 +547,17 @@ def task(ctx, config): When passed 'rhbuild' as a key, it will attempt to install an rh ceph build using ceph-deploy + Normally, the package management system will try to install or upgrade + specified packages as instructed. But if newer versions of these packages + to be installed have been installed on test node, we will have to uninstall + or downgrade them. To downgrade multiple packages in a single shot: + + tasks: + - install: + project: ceph + branch: hammer + downgrade_packages: ['librados2', 'librbd1'] + Reminder regarding teuthology-suite side effects: The teuthology-suite command always adds the following: diff --git a/teuthology/task/install/rpm.py b/teuthology/task/install/rpm.py index dda6324f7..8c2678d04 100644 --- a/teuthology/task/install/rpm.py +++ b/teuthology/task/install/rpm.py @@ -1,6 +1,8 @@ import logging import os.path +from distutils.version import LooseVersion + from teuthology.config import config as teuth_config from teuthology.orchestra import run from teuthology import packaging @@ -99,6 +101,38 @@ def _zypper_removerepo(remote, repo_list): 'sudo', 'zypper', '-n', 'removerepo', repo['name'], ]) + +def _downgrade_packages(ctx, remote, pkgs, pkg_version, config): + """ + Downgrade packages listed by 'downgrade_packages' + + Downgrade specified packages to given version. The list of packages + downgrade is provided by 'downgrade_packages' as a property of "install" + task. + + :param ctx: the argparse.Namespace object + :param remote: the teuthology.orchestra.remote.Remote object + :param pkgs: list of package names to install + :param pkg_version: the version to which all packages will be downgraded + :param config: the config dict + :return: list of package names from 'pkgs' which are not yet + installed/downgraded + """ + downgrade_pkgs = config.get('downgrade_packages', []) + if not downgrade_pkgs: + return pkgs + # assuming we are going to downgrade packages with the same version + first_pkg = downgrade_pkgs[0] + installed_version = packaging.get_package_version(remote, first_pkg) + assert installed_version, "failed to get version of {}".format(first_pkg) + assert LooseVersion(installed_version) < LooseVersion(pkg_version) + # to compose package name like "librados2-0.94.10-87.g116a558.el7" + pkgs_opt = ['-'.join([pkg, pkg_version]) for pkg in downgrade_pkgs] + downgrade_cmd = 'sudo yum -y downgrade {}'.format(' '.join(pkgs_opt)) + remote.run(args=downgrade_cmd.format(pkgs=pkgs_opt)) + return [pkg for pkg in pkgs if pkg not in downgrade_pkgs] + + def _update_package_list_and_install(ctx, remote, rpm, config): """ Installs the repository for the relevant branch, then installs @@ -159,6 +193,9 @@ def _update_package_list_and_install(ctx, remote, rpm, config): else: remove_cmd = 'sudo yum -y remove' install_cmd = 'sudo yum -y install' + # to compose version string like "0.94.10-87.g116a558.el7" + pkg_version = '.'.join([builder.version, builder.dist_release]) + rpm = _downgrade_packages(ctx, remote, rpm, pkg_version, config) for cpack in rpm: if ldir: -- 2.47.3