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
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
...

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)