Adding package versioning logic to package_command

This change adds the ability to provide specific package versions to
Distro.install_packages and subsequently Distro.package_command. In order
to effectively use Distro.install_packages, one is now able to pass a
variety of formats in order to easily manage package requirements. These
are examples of what can be passed:
- "package"
- ["package1","package2"]
- ("package",)
- ("package", "version")
- [("package1",)("package2",)]
- [("package1", "version1"),("package2","version2")]

This change also adds the option to install a specific version for the
puppet configuration module.  This is especially important here as
successful puppet deployments are highly reliant on specific puppet
versions.
This commit is contained in:
Craig Tracey 2013-01-27 21:48:03 -05:00
parent 37b5ae9ce1
commit 3a2a527531
6 changed files with 58 additions and 12 deletions

View File

@ -62,7 +62,7 @@ def handle(_name, cfg, cloud, log, _args):
if not ls_cloudcfg:
return
cloud.distro.install_packages(["landscape-client"])
cloud.distro.install_packages(('landscape-client',))
merge_data = [
LSC_BUILTIN_CFG,

View File

@ -59,8 +59,14 @@ def handle(name, cfg, cloud, log, _args):
# Start by installing the puppet package if necessary...
install = util.get_cfg_option_bool(puppet_cfg, 'install', True)
if install:
cloud.distro.install_packages(["puppet"])
version = util.get_cfg_option_str(puppet_cfg, 'version', None)
if not install and version:
log.warn(("Puppet install set false but version supplied,"
" doing nothing."))
elif install:
log.debug(("Attempting to install puppet %s,"),
version if version else 'latest')
cloud.distro.install_packages(('puppet', version))
# ... and then update the puppet configuration
if 'conf' in puppet_cfg:

View File

@ -31,7 +31,7 @@ def handle(name, cfg, cloud, log, _args):
salt_cfg = cfg['salt_minion']
# Start by installing the salt package ...
cloud.distro.install_packages(["salt-minion"])
cloud.distro.install_packages(('salt-minion',))
# Ensure we can configure files at the right dir
config_dir = salt_cfg.get("config_dir", '/etc/salt')

View File

@ -65,7 +65,7 @@ class Distro(distros.Distro):
def install_packages(self, pkglist):
self.update_package_sources()
self.package_command('install', pkglist)
self.package_command('install', pkgs=pkglist)
def _write_network(self, settings):
util.write_file(self.network_conf_fn, settings)
@ -142,15 +142,24 @@ class Distro(distros.Distro):
# This ensures that the correct tz will be used for the system
util.copy(tz_file, self.tz_local_fn)
def package_command(self, command, args=None):
def package_command(self, command, args=None, pkgs=[]):
e = os.environ.copy()
# See: http://tiny.cc/kg91fw
# Or: http://tiny.cc/mh91fw
e['DEBIAN_FRONTEND'] = 'noninteractive'
cmd = ['apt-get', '--option', 'Dpkg::Options::=--force-confold',
'--assume-yes', '--quiet', command]
if args:
'--assume-yes', '--quiet']
if args and isinstance(args, str):
cmd.append(args)
elif args and isinstance(args, list):
cmd.extend(args)
cmd.append(command)
pkglist = util.expand_package_list('%s=%s', pkgs)
cmd.extend(pkglist)
# Allow the output of this to flow outwards (ie not be captured)
util.subp(cmd, env=e, capture=False)

View File

@ -63,7 +63,7 @@ class Distro(distros.Distro):
self.osfamily = 'redhat'
def install_packages(self, pkglist):
self.package_command('install', pkglist)
self.package_command('install', pkgs=pkglist)
def _adjust_resolve(self, dns_servers, search_servers):
try:
@ -208,7 +208,7 @@ class Distro(distros.Distro):
# This ensures that the correct tz will be used for the system
util.copy(tz_file, self.tz_local_fn)
def package_command(self, command, args=None):
def package_command(self, command, args=None, pkgs=[]):
cmd = ['yum']
# If enabled, then yum will be tolerant of errors on the command line
# with regard to packages.
@ -219,9 +219,17 @@ class Distro(distros.Distro):
# Determines whether or not yum prompts for confirmation
# of critical actions. We don't want to prompt...
cmd.append("-y")
cmd.append(command)
if args:
if args and isinstance(args, str):
cmd.append(args)
elif args and isinstance(args, list):
cmd.extend(args)
cmd.append(command)
pkglist = util.expand_package_list('%s-%s', pkgs)
cmd.extend(pkglist)
# Allow the output of this to flow outwards (ie not be captured)
util.subp(cmd, capture=False)

View File

@ -1560,3 +1560,26 @@ def is_partition(device):
device = device[5:]
return os.path.isfile("/sys/class/block/%s/partition" % device)
def expand_package_list(version_fmt, pkgs):
# we will accept tuples, lists of tuples, or just plain lists
if not isinstance(pkgs, list):
pkgs = [pkgs]
pkglist = []
for pkg in pkgs:
if isinstance(pkg, str):
pkglist.append(pkg)
continue
if len(pkg) < 1 or len(pkg) > 2:
raise RuntimeError("Invalid package_command tuple.")
if len(pkg) == 2 and pkg[1]:
pkglist.append(version_fmt % pkg)
continue
pkglist.append(pkg[0])
return pkglist