diff options
author | Scott Moser <smoser@brickies.net> | 2017-01-10 11:25:30 -0500 |
---|---|---|
committer | Scott Moser <smoser@brickies.net> | 2017-01-10 11:25:30 -0500 |
commit | f0d495b80ac0b4b0a33c7fc7c6c3305a17dd8621 (patch) | |
tree | 5cd82dc768f69682a25e2c57abfb28f26d23d50f | |
parent | 7bdde5eda9e62a2362cfa71ae984b5ebbcdb795f (diff) | |
download | cloud-init-git-f0d495b80ac0b4b0a33c7fc7c6c3305a17dd8621.tar.gz |
Import version 0.7.5-0ubuntu1.11ubuntu/0.7.5-0ubuntu1.11
Imported using git-import-dsc
-rw-r--r-- | debian/changelog | 13 | ||||
-rw-r--r-- | debian/patches/lp-1461242-generate-ed25519-host-keys.patch | 115 | ||||
-rw-r--r-- | debian/patches/lp-1469260-fix-consumption-of-vendor-data.patch | 162 | ||||
-rw-r--r-- | debian/patches/series | 2 |
4 files changed, 292 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog index 60b31857..ad305204 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,16 @@ +cloud-init (0.7.5-0ubuntu1.11) trusty; urgency=medium + + [ Felipe Reyes ] + * d/patches/fix-consumption-of-vendor-data.patch: + - Fix consumption of vendor-data in OpenStack to allow namespacing + (LP: #1469260). + + [ Scott Moser ] + * d/patches/lp-1461242-generate-ed25519-host-keys.patch: + - ssh: generate ed25519 host keys if supported (LP: #1461242) + + -- Scott Moser <smoser@ubuntu.com> Fri, 11 Sep 2015 20:22:00 -0400 + cloud-init (0.7.5-0ubuntu1.10) trusty; urgency=medium [ Daniel Watkins ] diff --git a/debian/patches/lp-1461242-generate-ed25519-host-keys.patch b/debian/patches/lp-1461242-generate-ed25519-host-keys.patch new file mode 100644 index 00000000..f4088bd2 --- /dev/null +++ b/debian/patches/lp-1461242-generate-ed25519-host-keys.patch @@ -0,0 +1,115 @@ +Author: Scott Moser <smoser@ubuntu.com> +Bug: https://launchpad.net/bugs/1461242 +Applied-Upstream: yes +Origin: http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/revision/1125 +Description: ssh: generate ed25519 host keys if supported + . + now we attempt to generate ed25519 host keys. + If ssh-keygen does not support it, a debug log message will be written. + +=== modified file 'cloudinit/config/cc_ssh.py' +--- a/cloudinit/config/cc_ssh.py ++++ b/cloudinit/config/cc_ssh.py +@@ -20,6 +20,7 @@ + + import glob + import os ++import sys + + # Ensure this is aliased to a name not 'distros' + # since the module attribute 'distros' +@@ -33,26 +34,18 @@ DISABLE_ROOT_OPTS = ("no-port-forwarding + "no-X11-forwarding,command=\"echo \'Please login as the user \\\"$USER\\\" " + "rather than the user \\\"root\\\".\';echo;sleep 10\"") + +-KEY_2_FILE = { +- "rsa_private": ("/etc/ssh/ssh_host_rsa_key", 0600), +- "rsa_public": ("/etc/ssh/ssh_host_rsa_key.pub", 0644), +- "dsa_private": ("/etc/ssh/ssh_host_dsa_key", 0600), +- "dsa_public": ("/etc/ssh/ssh_host_dsa_key.pub", 0644), +- "ecdsa_private": ("/etc/ssh/ssh_host_ecdsa_key", 0600), +- "ecdsa_public": ("/etc/ssh/ssh_host_ecdsa_key.pub", 0644), +-} +- +-PRIV_2_PUB = { +- 'rsa_private': 'rsa_public', +- 'dsa_private': 'dsa_public', +- 'ecdsa_private': 'ecdsa_public', +-} +- +-KEY_GEN_TPL = 'o=$(ssh-keygen -yf "%s") && echo "$o" root@localhost > "%s"' ++GENERATE_KEY_NAMES = ['rsa', 'dsa', 'ecdsa', 'ed25519'] ++KEY_FILE_TPL = '/etc/ssh/ssh_host_%s_key' + +-GENERATE_KEY_NAMES = ['rsa', 'dsa', 'ecdsa'] ++CONFIG_KEY_TO_FILE = {} ++PRIV_TO_PUB = {} ++for k in GENERATE_KEY_NAMES: ++ CONFIG_KEY_TO_FILE.update({"%s_private" % k: (KEY_FILE_TPL % k, 0o600)}) ++ CONFIG_KEY_TO_FILE.update( ++ {"%s_public" % k: (KEY_FILE_TPL % k + ".pub", 0o600)}) ++ PRIV_TO_PUB["%s_private" % k] = "%s_public" % k + +-KEY_FILE_TPL = '/etc/ssh/ssh_host_%s_key' ++KEY_GEN_TPL = 'o=$(ssh-keygen -yf "%s") && echo "$o" root@localhost > "%s"' + + + def handle(_name, cfg, cloud, log, _args): +@@ -69,15 +62,15 @@ def handle(_name, cfg, cloud, log, _args + if "ssh_keys" in cfg: + # if there are keys in cloud-config, use them + for (key, val) in cfg["ssh_keys"].iteritems(): +- if key in KEY_2_FILE: +- tgt_fn = KEY_2_FILE[key][0] +- tgt_perms = KEY_2_FILE[key][1] ++ if key in CONFIG_KEY_TO_FILE: ++ tgt_fn = CONFIG_KEY_TO_FILE[key][0] ++ tgt_perms = CONFIG_KEY_TO_FILE[key][1] + util.write_file(tgt_fn, val, tgt_perms) + +- for (priv, pub) in PRIV_2_PUB.iteritems(): ++ for (priv, pub) in PRIV_TO_PUB.items(): + if pub in cfg['ssh_keys'] or not priv in cfg['ssh_keys']: + continue +- pair = (KEY_2_FILE[priv][0], KEY_2_FILE[pub][0]) ++ pair = (CONFIG_KEY_TO_FILE[priv][0], CONFIG_KEY_TO_FILE[pub][0]) + cmd = ['sh', '-xc', KEY_GEN_TPL % pair] + try: + # TODO(harlowja): Is this guard needed? +@@ -92,18 +85,28 @@ def handle(_name, cfg, cloud, log, _args + genkeys = util.get_cfg_option_list(cfg, + 'ssh_genkeytypes', + GENERATE_KEY_NAMES) ++ lang_c = os.environ.copy() ++ lang_c['LANG'] = 'C' + for keytype in genkeys: + keyfile = KEY_FILE_TPL % (keytype) ++ if os.path.exists(keyfile): ++ continue + util.ensure_dir(os.path.dirname(keyfile)) +- if not os.path.exists(keyfile): +- cmd = ['ssh-keygen', '-t', keytype, '-N', '', '-f', keyfile] ++ cmd = ['ssh-keygen', '-t', keytype, '-N', '', '-f', keyfile] ++ ++ # TODO(harlowja): Is this guard needed? ++ with util.SeLinuxGuard("/etc/ssh", recursive=True): + try: +- # TODO(harlowja): Is this guard needed? +- with util.SeLinuxGuard("/etc/ssh", recursive=True): +- util.subp(cmd, capture=False) +- except: +- util.logexc(log, "Failed generating key type %s to " +- "file %s", keytype, keyfile) ++ out, err = util.subp(cmd, capture=True, env=lang_c) ++ sys.stdout.write(out) ++ except util.ProcessExecutionError as e: ++ err = e.stderr.lower() ++ if (e.exit_code == 1 and ++ err.lower().startswith("unknown key")): ++ log.debug("ssh-keygen: unknown key type '%s'", keytype) ++ else: ++ util.logexc(log, "Failed generating key type %s to " ++ "file %s", keytype, keyfile) + + try: + (users, _groups) = ds.normalize_users_groups(cfg, cloud.distro) diff --git a/debian/patches/lp-1469260-fix-consumption-of-vendor-data.patch b/debian/patches/lp-1469260-fix-consumption-of-vendor-data.patch new file mode 100644 index 00000000..12ed15c3 --- /dev/null +++ b/debian/patches/lp-1469260-fix-consumption-of-vendor-data.patch @@ -0,0 +1,162 @@ +Author: Scott Moser <smoser@ubuntu.com> +Bug: https://bugs.launchpad.net/cloud-init/+bug/1469260 +Applied-Upstream: yes +Origin: http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/revision/1013 +Description: OpenStack: fix consumption of vendor-data to allow namespacing + . + Not all vendor data is destined for cloud-init. This sanely reads + the vendor data as a dict, array or a string. + +--- a/cloudinit/sources/DataSourceConfigDrive.py ++++ b/cloudinit/sources/DataSourceConfigDrive.py +@@ -125,7 +125,14 @@ + self.userdata_raw = results.get('userdata') + self.version = results['version'] + self.files.update(results.get('files', {})) +- self.vendordata_raw = results.get('vendordata') ++ vd = results.get('vendordata') ++ self.vendordata_pure = vd ++ try: ++ self.vendordata_raw = openstack.convert_vendordata_json(vd) ++ except ValueError as e: ++ LOG.warn("Invalid content in vendor-data: %s", e) ++ self.vendordata_raw = None ++ + return True + + +--- a/cloudinit/sources/DataSourceOpenStack.py ++++ b/cloudinit/sources/DataSourceOpenStack.py +@@ -143,13 +143,13 @@ + self.version = results['version'] + self.files.update(results.get('files', {})) + +- # if vendordata includes 'cloud-init', then read that explicitly +- # for cloud-init (for namespacing). + vd = results.get('vendordata') +- if isinstance(vd, dict) and 'cloud-init' in vd: +- self.vendordata_raw = vd['cloud-init'] +- else: +- self.vendordata_raw = vd ++ self.vendordata_pure = vd ++ try: ++ self.vendordata_raw = openstack.convert_vendordata_json(vd) ++ except ValueError as e: ++ LOG.warn("Invalid content in vendor-data: %s", e) ++ self.vendordata_raw = None + + return True + +--- a/cloudinit/sources/helpers/openstack.py ++++ b/cloudinit/sources/helpers/openstack.py +@@ -21,6 +21,7 @@ + import abc + import base64 + import copy ++import functools + import os + + from cloudinit import ec2_utils +@@ -196,6 +197,9 @@ + If not a valid location, raise a NonReadable exception. + """ + ++ load_json_anytype = functools.partial( ++ util.load_json, root_types=(dict, basestring, list)) ++ + def datafiles(version): + files = {} + files['metadata'] = ( +@@ -214,7 +218,7 @@ + files['vendordata'] = ( + self._path_join("openstack", version, 'vendor_data.json'), + False, +- util.load_json, ++ load_json_anytype, + ) + return files + +@@ -437,3 +441,28 @@ + return ec2_utils.get_instance_metadata(ssl_details=self.ssl_details, + timeout=self.timeout, + retries=self.retries) ++ ++ ++def convert_vendordata_json(data, recurse=True): ++ """ data: a loaded json *object* (strings, arrays, dicts). ++ return something suitable for cloudinit vendordata_raw. ++ ++ if data is: ++ None: return None ++ string: return string ++ list: return data ++ the list is then processed in UserDataProcessor ++ dict: return convert_vendordata_json(data.get('cloud-init')) ++ """ ++ if not data: ++ return None ++ if isinstance(data, (str, unicode, basestring)): ++ return data ++ if isinstance(data, list): ++ return copy.deepcopy(data) ++ if isinstance(data, dict): ++ if recurse is True: ++ return convert_vendordata_json(data.get('cloud-init'), ++ recurse=False) ++ raise ValueError("vendordata['cloud-init'] cannot be dict") ++ raise ValueError("Unknown data type for vendordata: %s" % type(data)) +--- a/tests/unittests/test_datasource/test_openstack.py ++++ b/tests/unittests/test_datasource/test_openstack.py +@@ -19,6 +19,7 @@ + import copy + import json + import re ++import unittest + + from StringIO import StringIO + +@@ -241,7 +242,8 @@ + self.assertEquals(EC2_META, ds_os.ec2_metadata) + self.assertEquals(USER_DATA, ds_os.userdata_raw) + self.assertEquals(2, len(ds_os.files)) +- self.assertEquals(VENDOR_DATA, ds_os.vendordata_raw) ++ self.assertEquals(VENDOR_DATA, ds_os.vendordata_pure) ++ self.assertEquals(ds_os.vendordata_raw, None) + + @hp.activate + def test_bad_datasource_meta(self): +@@ -299,3 +301,34 @@ + found = ds_os.get_data() + self.assertFalse(found) + self.assertIsNone(ds_os.version) ++ ++ ++class TestVendorDataLoading(unittest.TestCase): ++ def cvj(self, data): ++ return openstack.convert_vendordata_json(data) ++ ++ def test_vd_load_none(self): ++ # non-existant vendor-data should return none ++ self.assertIsNone(self.cvj(None)) ++ ++ def test_vd_load_string(self): ++ self.assertEqual(self.cvj("foobar"), "foobar") ++ ++ def test_vd_load_list(self): ++ data = [{'foo': 'bar'}, 'mystring', list(['another', 'list'])] ++ self.assertEqual(self.cvj(data), data) ++ ++ def test_vd_load_dict_no_ci(self): ++ self.assertEqual(self.cvj({'foo': 'bar'}), None) ++ ++ def test_vd_load_dict_ci_dict(self): ++ self.assertRaises(ValueError, self.cvj, ++ {'foo': 'bar', 'cloud-init': {'x': 1}}) ++ ++ def test_vd_load_dict_ci_string(self): ++ data = {'foo': 'bar', 'cloud-init': 'VENDOR_DATA'} ++ self.assertEqual(self.cvj(data), data['cloud-init']) ++ ++ def test_vd_load_dict_ci_list(self): ++ data = {'foo': 'bar', 'cloud-init': ['VD_1', 'VD_2']} ++ self.assertEqual(self.cvj(data), data['cloud-init']) diff --git a/debian/patches/series b/debian/patches/series index a238b1bc..8bd4a410 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -13,3 +13,5 @@ lp-1411582-azure-udev-ephemeral-disks.patch lp-1470880-fix-gce-az-determination.patch lp-1470890-include-regions-in-dynamic-mirror-discovery.patch lp-1490796-azure-fix-mount_cb-for-symlinks.patch +lp-1469260-fix-consumption-of-vendor-data.patch +lp-1461242-generate-ed25519-host-keys.patch |