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.
This commit is contained in:
Doug Hellmann 2012-03-23 16:45:27 -04:00
parent 679f33b242
commit 2340c1c589
6 changed files with 68 additions and 79 deletions

View File

@ -2,6 +2,7 @@
# RedHat Enterprise Linux 6 # RedHat Enterprise Linux 6
name: rhel-6 name: rhel-6
distro_pattern: redhat-6(.*) distro_pattern: redhat-6(.*)
packager_name: devstack.packaging.yum:YumPackager
commands: commands:
apache: apache:
restart: service httpd restart restart: service httpd restart
@ -250,6 +251,12 @@ components:
name: python-webob1.0 name: python-webob1.0
removable: true removable: true
version: 1.0* 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: pips:
- name: CherryPy - name: CherryPy
version: 3.2.2 version: 3.2.2
@ -659,6 +666,5 @@ components:
start: devstack.components.swift:SwiftRuntime start: devstack.components.swift:SwiftRuntime
stop: devstack.components.swift:SwiftRuntime stop: devstack.components.swift:SwiftRuntime
uninstall: devstack.components.swift:SwiftUninstaller uninstall: devstack.components.swift:SwiftUninstaller
packager_name: devstack.distros.rhel6:YumPackager
... ...

View File

@ -2,7 +2,7 @@
# Ubuntu 11 (Oneiric) # Ubuntu 11 (Oneiric)
distro_pattern: Ubuntu(.*)oneiric distro_pattern: Ubuntu(.*)oneiric
name: ubuntu-oneiric name: ubuntu-oneiric
packager_name: devstack.distros.oneiric:AptPackager packager_name: devstack.packaging.apt:AptPackager
commands: commands:
apache: apache:
restart: service apache2 restart restart: service apache2 restart
@ -617,6 +617,7 @@ components:
- name: rabbitmq-server - name: rabbitmq-server
removable: true removable: true
version: 2.5* version: 2.5*
packager_name: devstack.distros.oneiric:RabbitPackager
swift: swift:
action_classes: action_classes:
install: devstack.components.swift:SwiftInstaller install: devstack.components.swift:SwiftInstaller

View File

@ -128,14 +128,21 @@ class ComponentBase(object):
class PackageBasedComponentMixin(object): class PackageBasedComponentMixin(object):
"""Mix this into classes that need to manipulate
OS-level packages.
"""
PACKAGER_KEY_NAME = 'packager_name'
def __init__(self): def __init__(self):
self.default_packager = self.distro.get_default_package_manager() self.default_packager = self.distro.get_default_package_manager()
def get_packager(self, pkg_info): def get_packager(self, pkg_info):
if 'packager' in pkg_info: if self.PACKAGER_KEY_NAME in pkg_info:
packager_name = pkg_info['packager'] 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) packager = importer.import_entry_point(packager_name)(self.distro)
else: else:
LOG.debug('Using default package manager')
packager = self.default_packager packager = self.default_packager
return packager return packager
@ -199,8 +206,10 @@ class PkgInstallComponent(ComponentBase, PackageBasedComponentMixin):
for name in self.desired_subsystems: for name in self.desired_subsystems:
if name in self.subsystem_info: if name in self.subsystem_info:
# Todo handle duplicates/version differences? # Todo handle duplicates/version differences?
LOG.debug("Extending package list with packages for subsystem %s" % (name)) LOG.debug(
subsystem_pkgs = self.subsystem_info[name].get('packages', list()) "Extending package list with packages for subsystem %s",
name)
subsystem_pkgs = self.subsystem_info[name].get('packages', [])
pkg_list.extend(subsystem_pkgs) pkg_list.extend(subsystem_pkgs)
return pkg_list return pkg_list
@ -210,7 +219,8 @@ class PkgInstallComponent(ComponentBase, PackageBasedComponentMixin):
pkgs = self._get_packages() pkgs = self._get_packages()
if pkgs: if pkgs:
pkg_names = set([p['name'] for p in 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: with utils.progress_bar(INSTALL_TITLE, len(pkgs)) as p_bar:
for (i, p) in enumerate(pkgs): for (i, p) in enumerate(pkgs):
self.tracewriter.package_installed(p) self.tracewriter.package_installed(p)

View File

@ -46,33 +46,30 @@ class DBInstaller(db.DBInstaller):
sh.write_file('/etc/mysql/my.cnf', fc) sh.write_file('/etc/mysql/my.cnf', fc)
class AptPackager(apt.AptPackager): class RabbitPackager(apt.AptPackager):
def _remove_special(self, name, info): def _remove(self, pkg):
if name == 'rabbitmq-server': #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597 #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600 name = pkg['name']
LOG.debug("Handling special remove of %s." % (name)) LOG.debug("Handling special remove of %s." % (name))
pkg_full = self._format_pkg_name(name, info.get("version")) pkg_full = self._format_pkg_name(name, pkg.get("version"))
cmd = apt.APT_REMOVE + [pkg_full] cmd = apt.APT_REMOVE + [pkg_full]
self._execute_apt(cmd) self._execute_apt(cmd)
#probably useful to do this #probably useful to do this
time.sleep(1) time.sleep(1)
#purge #purge
cmd = apt.APT_PURGE + [pkg_full] cmd = apt.APT_PURGE + [pkg_full]
self._execute_apt(cmd) self._execute_apt(cmd)
return True return True
return False
def _install_special(self, name, info): def install(self, pkg):
if name == 'rabbitmq-server': #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597 #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600 name = pkg['name']
LOG.debug("Handling special install of %s." % (name)) LOG.debug("Handling special install of %s." % (name))
#this seems to be a temporary fix for that bug #this seems to be a temporary fix for that bug
with tempfile.TemporaryFile() as f: with tempfile.TemporaryFile() as f:
pkg_full = self._format_pkg_name(name, info.get("version")) pkg_full = self._format_pkg_name(name, pkg.get("version"))
cmd = apt.APT_INSTALL + [pkg_full] cmd = apt.APT_INSTALL + [pkg_full]
self._execute_apt(cmd, stdout_fh=f, stderr_fh=f) self._execute_apt(cmd, stdout_fh=f, stderr_fh=f)
return True
return False

View File

@ -33,18 +33,6 @@ LOG = logging.getLogger(__name__)
SOCKET_CONF = "/etc/httpd/conf.d/wsgi-socket-prefix.conf" SOCKET_CONF = "/etc/httpd/conf.d/wsgi-socket-prefix.conf"
HTTPD_CONF = '/etc/httpd/conf/httpd.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 # See: http://wiki.libvirt.org/page/SSHPolicyKitSetup
# FIXME: take from distro config?? # FIXME: take from distro config??
LIBVIRT_POLICY_FN = "/etc/polkit-1/localauthority/50-local.d/50-libvirt-access.pkla" 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 return configs_made
class YumPackager(yum.YumPackager): class YumPackagerWithRelinks(yum.YumPackager):
def _remove_special(self, name, info): def _remove(self, pkg):
if name in RHEL_RELINKS: response = yum.YumPackager._remove(self, pkg)
# Note: we don't return true here so that if response:
# the normal package cleanup happens... options = pkg.get('packager_options', {})
(_, tgt) = RHEL_RELINKS.get(name) links = options.get('links', [])
if sh.islink(tgt): for src, tgt in links:
sh.unlink(tgt) if sh.islink(tgt):
return False sh.unlink(tgt)
return response
def _install_special(self, name, info): def install(self, pkg):
if name in RHEL_RELINKS: yum.YumPackager.install(self, pkg)
full_pkg_name = self._format_pkg_name(name, info.get("version")) options = pkg.get('packager_options', {})
install_cmd = yum.YUM_INSTALL + [full_pkg_name] links = options.get('links', [])
self._execute_yum(install_cmd) for src, tgt in links:
(src, tgt) = RHEL_RELINKS.get(name)
if not sh.islink(tgt): if not sh.islink(tgt):
# This is actually a feature, EPEL must not conflict # This is actually a feature, EPEL must not conflict
# with RHEL, so X pkg installs newer version in # 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 # This of course doesn't work when running from git
# like devstack does.... # like devstack does....
sh.symlink(src, tgt) sh.symlink(src, tgt)
return True return True
else:
return False

View File

@ -60,8 +60,6 @@ class AptPackager(pack.Packager):
def _remove(self, pkg): def _remove(self, pkg):
name = pkg['name'] name = pkg['name']
if self._remove_special(name, pkg):
return True
pkg_full = self._format_pkg_name(name, pkg.get("version")) pkg_full = self._format_pkg_name(name, pkg.get("version"))
cmd = APT_DO_REMOVE + [pkg_full] cmd = APT_DO_REMOVE + [pkg_full]
self._execute_apt(cmd) self._execute_apt(cmd)
@ -71,15 +69,6 @@ class AptPackager(pack.Packager):
def install(self, pkg): def install(self, pkg):
name = pkg['name'] name = pkg['name']
if self._install_special(name, pkg): pkg_full = self._format_pkg_name(name, pkg.get("version"))
return cmd = APT_INSTALL + [pkg_full]
else: self._execute_apt(cmd)
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