cloud-init-dev team mailing list archive
-
cloud-init-dev team
-
Mailing list archive
-
Message #00213
[Merge] lp:~craigtracey/cloud-init/package-versions into lp:cloud-init
Craig Tracey has proposed merging lp:~craigtracey/cloud-init/package-versions into lp:cloud-init.
Requested reviews:
cloud init development team (cloud-init-dev)
Related bugs:
Bug #1108047 in cloud-init: "cloud-init should have generic mechanism for installing specific package versions"
https://bugs.launchpad.net/cloud-init/+bug/1108047
For more details, see:
https://code.launchpad.net/~craigtracey/cloud-init/package-versions/+merge/145209
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.
--
https://code.launchpad.net/~craigtracey/cloud-init/package-versions/+merge/145209
Your team cloud init development team is requested to review the proposed merge of lp:~craigtracey/cloud-init/package-versions into lp:cloud-init.
=== modified file 'cloudinit/config/cc_landscape.py'
--- cloudinit/config/cc_landscape.py 2012-10-28 02:25:48 +0000
+++ cloudinit/config/cc_landscape.py 2013-01-28 17:07:23 +0000
@@ -62,7 +62,7 @@
if not ls_cloudcfg:
return
- cloud.distro.install_packages(["landscape-client"])
+ cloud.distro.install_packages(('landscape-client',))
merge_data = [
LSC_BUILTIN_CFG,
=== modified file 'cloudinit/config/cc_puppet.py'
--- cloudinit/config/cc_puppet.py 2012-12-14 02:06:32 +0000
+++ cloudinit/config/cc_puppet.py 2013-01-28 17:07:23 +0000
@@ -59,8 +59,14 @@
# 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:
=== modified file 'cloudinit/config/cc_salt_minion.py'
--- cloudinit/config/cc_salt_minion.py 2012-10-28 02:25:48 +0000
+++ cloudinit/config/cc_salt_minion.py 2013-01-28 17:07:23 +0000
@@ -31,7 +31,7 @@
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')
=== modified file 'cloudinit/distros/debian.py'
--- cloudinit/distros/debian.py 2013-01-15 21:08:43 +0000
+++ cloudinit/distros/debian.py 2013-01-28 17:07:23 +0000
@@ -65,7 +65,7 @@
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 @@
# 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)
=== modified file 'cloudinit/distros/rhel.py'
--- cloudinit/distros/rhel.py 2013-01-15 21:08:43 +0000
+++ cloudinit/distros/rhel.py 2013-01-28 17:07:23 +0000
@@ -63,7 +63,7 @@
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 @@
# 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 @@
# Determines whether or not yum prompts for confirmation
# of critical actions. We don't want to prompt...
cmd.append("-y")
+
+ if args and isinstance(args, str):
+ cmd.append(args)
+ elif args and isinstance(args, list):
+ cmd.extend(args)
+
cmd.append(command)
- if args:
- cmd.extend(args)
+
+ 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)
=== modified file 'cloudinit/util.py'
--- cloudinit/util.py 2013-01-17 00:46:30 +0000
+++ cloudinit/util.py 2013-01-28 17:07:23 +0000
@@ -1560,3 +1560,26 @@
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