summaryrefslogtreecommitdiff
path: root/cloudinit
diff options
context:
space:
mode:
authorJoshua Harlow <harlowja@yahoo-inc.com>2013-01-30 21:39:49 -0800
committerJoshua Harlow <harlowja@yahoo-inc.com>2013-01-30 21:39:49 -0800
commit9df0a78e527875d1bee2be02e477176c35a971b8 (patch)
treec1f99d1e5772b90165f7abbdf5a8277c5f15b83d /cloudinit
parent7537cec4b6fdd27f9ad667f8b4682719b8da493c (diff)
parent9ced60371239eb961e9919f13bda8b496e077411 (diff)
downloadvyos-cloud-init-9df0a78e527875d1bee2be02e477176c35a971b8.tar.gz
vyos-cloud-init-9df0a78e527875d1bee2be02e477176c35a971b8.zip
Adding package versioning logic to package installation.
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.
Diffstat (limited to 'cloudinit')
-rw-r--r--cloudinit/config/cc_landscape.py2
-rw-r--r--cloudinit/config/cc_puppet.py10
-rw-r--r--cloudinit/config/cc_salt_minion.py2
-rw-r--r--cloudinit/distros/debian.py17
-rw-r--r--cloudinit/distros/rhel.py16
-rw-r--r--cloudinit/util.py32
6 files changed, 64 insertions, 15 deletions
diff --git a/cloudinit/config/cc_landscape.py b/cloudinit/config/cc_landscape.py
index 02610dd0..2efdff79 100644
--- a/cloudinit/config/cc_landscape.py
+++ b/cloudinit/config/cc_landscape.py
@@ -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,
diff --git a/cloudinit/config/cc_puppet.py b/cloudinit/config/cc_puppet.py
index e9a0a0f4..471a1a8a 100644
--- a/cloudinit/config/cc_puppet.py
+++ b/cloudinit/config/cc_puppet.py
@@ -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:
diff --git a/cloudinit/config/cc_salt_minion.py b/cloudinit/config/cc_salt_minion.py
index f3eede18..53013dcb 100644
--- a/cloudinit/config/cc_salt_minion.py
+++ b/cloudinit/config/cc_salt_minion.py
@@ -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')
diff --git a/cloudinit/distros/debian.py b/cloudinit/distros/debian.py
index 49b73477..1a8e927b 100644
--- a/cloudinit/distros/debian.py
+++ b/cloudinit/distros/debian.py
@@ -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)
diff --git a/cloudinit/distros/rhel.py b/cloudinit/distros/rhel.py
index e65be8d7..2f91e386 100644
--- a/cloudinit/distros/rhel.py
+++ b/cloudinit/distros/rhel.py
@@ -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)
diff --git a/cloudinit/util.py b/cloudinit/util.py
index c0ea8d91..ffe844b2 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -402,10 +402,9 @@ def get_cfg_option_list(yobj, key, default=None):
return []
val = yobj[key]
if isinstance(val, (list)):
- # Should we ensure they are all strings??
- cval = [str(v) for v in val]
+ cval = [v for v in val]
return cval
- if not isinstance(val, (str, basestring)):
+ if not isinstance(val, (basestring)):
val = str(val)
return [val]
@@ -1560,3 +1559,30 @@ 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, basestring):
+ pkglist.append(pkg)
+ continue
+
+ if isinstance(pkg, (tuple, list)):
+ if len(pkg) < 1 or len(pkg) > 2:
+ raise RuntimeError("Invalid package & version tuple.")
+
+ if len(pkg) == 2 and pkg[1]:
+ pkglist.append(version_fmt % tuple(pkg))
+ continue
+
+ pkglist.append(pkg[0])
+
+ else:
+ raise RuntimeError("Invalid package type.")
+
+ return pkglist