From 2340c1c58909af0db8131f976840ad439bf66b27 Mon Sep 17 00:00:00 2001 From: Doug Hellmann Date: Fri, 23 Mar 2012 16:45:27 -0400 Subject: [PATCH] Move package-specific logic into custom package manager classes and allow the distro file to specify when to use them. There are two examples, one for Rabbit on Oneiric and another more general for managing symlinks needed after installing a package with Yum. --- conf/distros/rhel-6.yaml | 8 ++++- conf/distros/ubuntu-oneiric.yaml | 3 +- devstack/component.py | 20 +++++++++--- devstack/distros/oneiric.py | 53 +++++++++++++++----------------- devstack/distros/rhel6.py | 46 ++++++++++----------------- devstack/packaging/apt.py | 17 ++-------- 6 files changed, 68 insertions(+), 79 deletions(-) diff --git a/conf/distros/rhel-6.yaml b/conf/distros/rhel-6.yaml index 98ce93bb..ab3b9cd3 100644 --- a/conf/distros/rhel-6.yaml +++ b/conf/distros/rhel-6.yaml @@ -2,6 +2,7 @@ # RedHat Enterprise Linux 6 name: rhel-6 distro_pattern: redhat-6(.*) +packager_name: devstack.packaging.yum:YumPackager commands: apache: restart: service httpd restart @@ -250,6 +251,12 @@ components: name: python-webob1.0 removable: true version: 1.0* + packager_name: devstack.distros.rhel6:YumPackagerWithRelinks + packager_options: + links: + - source: /usr/lib/python2.6/site-packages/WebOb-1.0.8-py2.6.egg/webob/ + target: /usr/lib/python2.6/site-packages/webob + pips: - name: CherryPy version: 3.2.2 @@ -659,6 +666,5 @@ components: start: devstack.components.swift:SwiftRuntime stop: devstack.components.swift:SwiftRuntime uninstall: devstack.components.swift:SwiftUninstaller -packager_name: devstack.distros.rhel6:YumPackager ... diff --git a/conf/distros/ubuntu-oneiric.yaml b/conf/distros/ubuntu-oneiric.yaml index 4918723b..3257319b 100644 --- a/conf/distros/ubuntu-oneiric.yaml +++ b/conf/distros/ubuntu-oneiric.yaml @@ -2,7 +2,7 @@ # Ubuntu 11 (Oneiric) distro_pattern: Ubuntu(.*)oneiric name: ubuntu-oneiric -packager_name: devstack.distros.oneiric:AptPackager +packager_name: devstack.packaging.apt:AptPackager commands: apache: restart: service apache2 restart @@ -617,6 +617,7 @@ components: - name: rabbitmq-server removable: true version: 2.5* + packager_name: devstack.distros.oneiric:RabbitPackager swift: action_classes: install: devstack.components.swift:SwiftInstaller diff --git a/devstack/component.py b/devstack/component.py index fc2eb746..1a144ea7 100644 --- a/devstack/component.py +++ b/devstack/component.py @@ -128,14 +128,21 @@ class ComponentBase(object): class PackageBasedComponentMixin(object): + """Mix this into classes that need to manipulate + OS-level packages. + """ + PACKAGER_KEY_NAME = 'packager_name' + def __init__(self): self.default_packager = self.distro.get_default_package_manager() def get_packager(self, pkg_info): - if 'packager' in pkg_info: - packager_name = pkg_info['packager'] + if self.PACKAGER_KEY_NAME in pkg_info: + packager_name = pkg_info[self.PACKAGER_KEY_NAME] + LOG.debug('Loading custom package manager %s', packager_name) packager = importer.import_entry_point(packager_name)(self.distro) else: + LOG.debug('Using default package manager') packager = self.default_packager return packager @@ -199,8 +206,10 @@ class PkgInstallComponent(ComponentBase, PackageBasedComponentMixin): for name in self.desired_subsystems: if name in self.subsystem_info: # Todo handle duplicates/version differences? - LOG.debug("Extending package list with packages for subsystem %s" % (name)) - subsystem_pkgs = self.subsystem_info[name].get('packages', list()) + LOG.debug( + "Extending package list with packages for subsystem %s", + name) + subsystem_pkgs = self.subsystem_info[name].get('packages', []) pkg_list.extend(subsystem_pkgs) return pkg_list @@ -210,7 +219,8 @@ class PkgInstallComponent(ComponentBase, PackageBasedComponentMixin): pkgs = self._get_packages() if pkgs: pkg_names = set([p['name'] for p in pkgs]) - LOG.info("Setting up %s packages (%s)" % (len(pkg_names), ", ".join(pkg_names))) + LOG.info("Setting up %s packages (%s)", + len(pkg_names), ", ".join(pkg_names)) with utils.progress_bar(INSTALL_TITLE, len(pkgs)) as p_bar: for (i, p) in enumerate(pkgs): self.tracewriter.package_installed(p) diff --git a/devstack/distros/oneiric.py b/devstack/distros/oneiric.py index 0cad3b00..f15cacc8 100644 --- a/devstack/distros/oneiric.py +++ b/devstack/distros/oneiric.py @@ -46,33 +46,30 @@ class DBInstaller(db.DBInstaller): sh.write_file('/etc/mysql/my.cnf', fc) -class AptPackager(apt.AptPackager): +class RabbitPackager(apt.AptPackager): - def _remove_special(self, name, info): - if name == 'rabbitmq-server': - #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597 - #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600 - LOG.debug("Handling special remove of %s." % (name)) - pkg_full = self._format_pkg_name(name, info.get("version")) - cmd = apt.APT_REMOVE + [pkg_full] - self._execute_apt(cmd) - #probably useful to do this - time.sleep(1) - #purge - cmd = apt.APT_PURGE + [pkg_full] - self._execute_apt(cmd) - return True - return False + def _remove(self, pkg): + #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597 + #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600 + name = pkg['name'] + LOG.debug("Handling special remove of %s." % (name)) + pkg_full = self._format_pkg_name(name, pkg.get("version")) + cmd = apt.APT_REMOVE + [pkg_full] + self._execute_apt(cmd) + #probably useful to do this + time.sleep(1) + #purge + cmd = apt.APT_PURGE + [pkg_full] + self._execute_apt(cmd) + return True - def _install_special(self, name, info): - if name == 'rabbitmq-server': - #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597 - #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600 - LOG.debug("Handling special install of %s." % (name)) - #this seems to be a temporary fix for that bug - with tempfile.TemporaryFile() as f: - pkg_full = self._format_pkg_name(name, info.get("version")) - cmd = apt.APT_INSTALL + [pkg_full] - self._execute_apt(cmd, stdout_fh=f, stderr_fh=f) - return True - return False + def install(self, pkg): + #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597 + #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600 + name = pkg['name'] + LOG.debug("Handling special install of %s." % (name)) + #this seems to be a temporary fix for that bug + with tempfile.TemporaryFile() as f: + pkg_full = self._format_pkg_name(name, pkg.get("version")) + cmd = apt.APT_INSTALL + [pkg_full] + self._execute_apt(cmd, stdout_fh=f, stderr_fh=f) diff --git a/devstack/distros/rhel6.py b/devstack/distros/rhel6.py index a24e98d2..0edc6b56 100644 --- a/devstack/distros/rhel6.py +++ b/devstack/distros/rhel6.py @@ -33,18 +33,6 @@ LOG = logging.getLogger(__name__) SOCKET_CONF = "/etc/httpd/conf.d/wsgi-socket-prefix.conf" HTTPD_CONF = '/etc/httpd/conf/httpd.conf' -# Need to relink for rhel (not a bug!) -RHEL_RELINKS = { - 'python-webob1.0': ( - '/usr/lib/python2.6/site-packages/WebOb-1.0.8-py2.6.egg/webob/', - '/usr/lib/python2.6/site-packages/webob' - ), - 'python-nose1.1': ( - '/usr/lib/python2.6/site-packages/nose-1.1.2-py2.6.egg/nose/', - '/usr/lib/python2.6/site-packages/nose', - ) -} - # See: http://wiki.libvirt.org/page/SSHPolicyKitSetup # FIXME: take from distro config?? LIBVIRT_POLICY_FN = "/etc/polkit-1/localauthority/50-local.d/50-libvirt-access.pkla" @@ -116,23 +104,23 @@ class NovaInstaller(nova.NovaInstaller): return configs_made -class YumPackager(yum.YumPackager): +class YumPackagerWithRelinks(yum.YumPackager): - def _remove_special(self, name, info): - if name in RHEL_RELINKS: - # Note: we don't return true here so that - # the normal package cleanup happens... - (_, tgt) = RHEL_RELINKS.get(name) - if sh.islink(tgt): - sh.unlink(tgt) - return False + def _remove(self, pkg): + response = yum.YumPackager._remove(self, pkg) + if response: + options = pkg.get('packager_options', {}) + links = options.get('links', []) + for src, tgt in links: + if sh.islink(tgt): + sh.unlink(tgt) + return response - def _install_special(self, name, info): - if name in RHEL_RELINKS: - full_pkg_name = self._format_pkg_name(name, info.get("version")) - install_cmd = yum.YUM_INSTALL + [full_pkg_name] - self._execute_yum(install_cmd) - (src, tgt) = RHEL_RELINKS.get(name) + def install(self, pkg): + yum.YumPackager.install(self, pkg) + options = pkg.get('packager_options', {}) + links = options.get('links', []) + for src, tgt in links: if not sh.islink(tgt): # This is actually a feature, EPEL must not conflict # with RHEL, so X pkg installs newer version in @@ -141,6 +129,4 @@ class YumPackager(yum.YumPackager): # This of course doesn't work when running from git # like devstack does.... sh.symlink(src, tgt) - return True - else: - return False + return True diff --git a/devstack/packaging/apt.py b/devstack/packaging/apt.py index af7b4ad7..15ae3e9a 100644 --- a/devstack/packaging/apt.py +++ b/devstack/packaging/apt.py @@ -60,8 +60,6 @@ class AptPackager(pack.Packager): def _remove(self, pkg): name = pkg['name'] - if self._remove_special(name, pkg): - return True pkg_full = self._format_pkg_name(name, pkg.get("version")) cmd = APT_DO_REMOVE + [pkg_full] self._execute_apt(cmd) @@ -71,15 +69,6 @@ class AptPackager(pack.Packager): def install(self, pkg): name = pkg['name'] - if self._install_special(name, pkg): - return - else: - pkg_full = self._format_pkg_name(name, pkg.get("version")) - cmd = APT_INSTALL + [pkg_full] - self._execute_apt(cmd) - - def _remove_special(self, name, info): - return False - - def _install_special(self, name, info): - return False + pkg_full = self._format_pkg_name(name, pkg.get("version")) + cmd = APT_INSTALL + [pkg_full] + self._execute_apt(cmd)