~smoser/ubuntu/vivid/cloud-init/snappy

« back to all changes in this revision

Viewing changes to cloudinit/ec2_utils.py

  • Committer: Scott Moser
  • Date: 2015-02-27 20:55:58 UTC
  • mfrom: (355.2.8 vivid)
  • Revision ID: smoser@ubuntu.com-20150227205558-glrwdgxqkaz6zyxa
* Merge with vivid at 0.7.7~bzr1067-0ubuntu1
* New upstream snapshot.
  * fix broken consumption of gzipped user-data (LP: #1424900)
  * functional user-data on Azure again (LP: #1423972)
  * CloudStack: support fetching password from virtual router (LP: #1422388)
* New upstream snapshot.
  * Fix for ascii decode in DataSourceAzure (LP: #1422993).
* New upstream snapshot.
  * support for gpt partitioning, utilized in Azure [Daniel Watkins]
  * fix bug in exception handling in mount_cb.
* New upstream snapshot.
  * move to python3 (LP: #1247132)
  * systemd: run cloud-init before systemd-user-sessions.service
  * Use the GCE short hostname. (LP: #1383794)
  * Enable user-data encoding support for GCE. (LP: #1404311)
  * Update to use a newer and better OMNIBUS_URL
  * Be more tolerant of 'ssh_authorized_keys' types
  * Fix parse_ssh_config failing in ssh_util.py
  * Increase the robustness/configurability of the chef module.
  * retain trailing newline from template files when using
    jinja2 (LP: #1355343)
  * fix broken output handling (LP: #1387340)
  * digital ocean datasource
  * update url in config drive documentation
  * freebsd: enable correct behavior on Ec2.
  * freebsd: Use the proper virtio FreeBSD network interface name.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
18
 
19
19
import functools
20
 
import httplib
21
20
import json
22
21
 
23
22
from cloudinit import log as logging
25
24
from cloudinit import util
26
25
 
27
26
LOG = logging.getLogger(__name__)
28
 
SKIP_USERDATA_CODES = frozenset([httplib.NOT_FOUND])
 
27
SKIP_USERDATA_CODES = frozenset([url_helper.NOT_FOUND])
29
28
 
30
29
 
31
30
class MetadataLeafDecoder(object):
42
41
    def __call__(self, field, blob):
43
42
        if not blob:
44
43
            return blob
 
44
        try:
 
45
            blob = util.decode_binary(blob)
 
46
        except UnicodeDecodeError:
 
47
            return blob
45
48
        if self._maybe_json_object(blob):
46
49
            try:
47
50
                # Assume it's json, unless it fails parsing...
70
73
    def _parse(self, blob):
71
74
        leaves = {}
72
75
        children = []
 
76
        blob = util.decode_binary(blob)
 
77
 
73
78
        if not blob:
74
79
            return (leaves, children)
75
80
 
118
123
            child_url = url_helper.combine_url(base_url, c)
119
124
            if not child_url.endswith("/"):
120
125
                child_url += "/"
121
 
            child_blob = str(self._caller(child_url))
 
126
            child_blob = self._caller(child_url)
122
127
            child_contents[c] = self._materialize(child_blob, child_url)
123
128
        leaf_contents = {}
124
129
        for (field, resource) in leaves.items():
125
130
            leaf_url = url_helper.combine_url(base_url, resource)
126
 
            leaf_blob = str(self._caller(leaf_url))
 
131
            leaf_blob = self._caller(leaf_url)
127
132
            leaf_contents[field] = self._leaf_decoder(field, leaf_blob)
128
133
        joined = {}
129
134
        joined.update(child_contents)
160
165
                                         timeout=timeout,
161
166
                                         retries=retries,
162
167
                                         exception_cb=exception_cb)
163
 
        user_data = str(response)
 
168
        user_data = response.contents
164
169
    except url_helper.UrlError as e:
165
170
        if e.code not in SKIP_USERDATA_CODES:
166
171
            util.logexc(LOG, "Failed fetching userdata from url %s", ud_url)
180
185
    caller = functools.partial(util.read_file_or_url,
181
186
                               ssl_details=ssl_details, timeout=timeout,
182
187
                               retries=retries)
 
188
    def mcaller(url):
 
189
        return caller(url).contents
183
190
 
184
191
    try:
185
192
        response = caller(md_url)
186
 
        materializer = MetadataMaterializer(str(response),
187
 
                                            md_url, caller,
 
193
        materializer = MetadataMaterializer(response.contents,
 
194
                                            md_url, mcaller,
188
195
                                            leaf_decoder=leaf_decoder)
189
196
        md = materializer.materialize()
190
197
        if not isinstance(md, (dict)):