summaryrefslogtreecommitdiff
path: root/cloudinit/user_data.py
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/user_data.py')
-rw-r--r--cloudinit/user_data.py19
1 files changed, 16 insertions, 3 deletions
diff --git a/cloudinit/user_data.py b/cloudinit/user_data.py
index de6487d8..3f860f3b 100644
--- a/cloudinit/user_data.py
+++ b/cloudinit/user_data.py
@@ -29,6 +29,8 @@ from email.mime.multipart import MIMEMultipart
from email.mime.nonmultipart import MIMENonMultipart
from email.mime.text import MIMEText
+import six
+
from cloudinit import handlers
from cloudinit import log as logging
from cloudinit import util
@@ -106,7 +108,17 @@ class UserDataProcessor(object):
ctype = None
ctype_orig = part.get_content_type()
+ ctype_main = part.get_content_maintype()
payload = part.get_payload(decode=True)
+ # In Python 3, decoding the payload will ironically hand us a
+ # bytes object. 'decode' means to decode according to
+ # Content-Transfer-Encoding, not according to any charset in the
+ # Content-Type. So, if we end up with bytes, first try to decode
+ # to str via CT charset, and failing that, try utf-8 using
+ # surrogate escapes.
+ if six.PY3 and ctype_main == 'text' and isinstance(payload, bytes):
+ charset = part.get_charset() or 'utf-8'
+ payload = payload.decode(charset, errors='surrogateescape')
was_compressed = False
# When the message states it is of a gzipped content type ensure
@@ -120,6 +132,7 @@ class UserDataProcessor(object):
ctype_orig = None
was_compressed = True
except util.DecompressionError as e:
+ import pdb; pdb.set_trace()
LOG.warn("Failed decompressing payload from %s of length"
" %s due to: %s", ctype_orig, len(payload), e)
continue
@@ -235,7 +248,7 @@ class UserDataProcessor(object):
resp = util.read_file_or_url(include_url,
ssl_details=self.ssl_details)
if include_once_on and resp.ok():
- util.write_file(include_once_fn, str(resp), mode=0600)
+ util.write_file(include_once_fn, str(resp), mode=0o600)
if resp.ok():
content = str(resp)
else:
@@ -256,7 +269,7 @@ class UserDataProcessor(object):
# filename and type not be present
# or
# scalar(payload)
- if isinstance(ent, (str, basestring)):
+ if isinstance(ent, six.string_types):
ent = {'content': ent}
if not isinstance(ent, (dict)):
# TODO(harlowja) raise?
@@ -337,7 +350,7 @@ def convert_string(raw_data, headers=None):
data = util.decomp_gzip(raw_data)
if "mime-version:" in data[0:4096].lower():
msg = email.message_from_string(data)
- for (key, val) in headers.iteritems():
+ for (key, val) in headers.items():
_replace_header(msg, key, val)
else:
mtype = headers.get(CONTENT_TYPE, NOT_MULTIPART_TYPE)