← Back to team overview

yahoo-eng-team team mailing list archive

[Bug 1469260] [NEW] Custom vendor data causes cloud-init failure on 0.7.5

 

Public bug reported:

I encountered this issue when adding custom vendor data via nova-
compute. Originally the bug manifested as SSH host key generation
failing to fire when vendor data was present (example vendor data
below).

{"msg": "", "uuid": "4996e2b67d2941818646481453de1efe", "users":
[{"username": "erhudy", "sshPublicKeys": [], "uuid": "erhudy"}], "name":
"TestTenant"}

I launched a volume-backed instance, waited for it to fail, then
terminated it and mounted its root volume to examine the logs. What I
found was that cloud-init was failing to process vendor-data into MIME
multipart (note the absence of the line that indicates that cloud-init
is writing vendor-data.txt.i):

2015-06-25 21:41:02,178 - util.py[DEBUG]: Writing to /var/lib/cloud/instance/obj.pkl - wb: [256] 9751 bytes
2015-06-25 21:41:02,178 - util.py[DEBUG]: Writing to /var/lib/cloud/instances/65c9fb0c-0700-4f87-a22f-c59534e98dfb/user-data.txt - wb: [384] 0 bytes
2015-06-25 21:41:02,184 - util.py[DEBUG]: Writing to /var/lib/cloud/instances/65c9fb0c-0700-4f87-a22f-c59534e98dfb/user-data.txt.i - wb: [384] 345 bytes
2015-06-25 21:41:02,185 - util.py[DEBUG]: Writing to /var/lib/cloud/instances/65c9fb0c-0700-4f87-a22f-c59534e98dfb/vendor-data.txt - wb: [384] 234 bytes
2015-06-25 21:41:02,185 - util.py[DEBUG]: Reading from /proc/uptime (quiet=False)

After following the call chain all the way down, I found the problematic
code in user_data.py:

# Coverts a raw string into a mime message
def convert_string(raw_data, headers=None):
    if not raw_data:
        raw_data = ''
    if not headers:
        headers = {}
    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():
            _replace_header(msg, key, val)
    else:
        mtype = headers.get(CONTENT_TYPE, NOT_MULTIPART_TYPE)
        maintype, subtype = mtype.split("/", 1)
        msg = MIMEBase(maintype, subtype, *headers)
        msg.set_payload(data)
    return msg

raw_data in the case that is failing is a dictionary rather than the
expected string, so slicing into data causes a TypeError: unhashable
type exception.

I think this bug was fixed after a fashion in 0.7.7, where the call to
util.decomp_gzip() is now wrapped by util.decode_binary(), which appears
to always return a string.

** Affects: cloud-init
     Importance: Undecided
         Status: New

-- 
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to cloud-init.
https://bugs.launchpad.net/bugs/1469260

Title:
  Custom vendor data causes cloud-init failure on 0.7.5

Status in Init scripts for use on cloud images:
  New

Bug description:
  I encountered this issue when adding custom vendor data via nova-
  compute. Originally the bug manifested as SSH host key generation
  failing to fire when vendor data was present (example vendor data
  below).

  {"msg": "", "uuid": "4996e2b67d2941818646481453de1efe", "users":
  [{"username": "erhudy", "sshPublicKeys": [], "uuid": "erhudy"}],
  "name": "TestTenant"}

  I launched a volume-backed instance, waited for it to fail, then
  terminated it and mounted its root volume to examine the logs. What I
  found was that cloud-init was failing to process vendor-data into MIME
  multipart (note the absence of the line that indicates that cloud-init
  is writing vendor-data.txt.i):

  2015-06-25 21:41:02,178 - util.py[DEBUG]: Writing to /var/lib/cloud/instance/obj.pkl - wb: [256] 9751 bytes
  2015-06-25 21:41:02,178 - util.py[DEBUG]: Writing to /var/lib/cloud/instances/65c9fb0c-0700-4f87-a22f-c59534e98dfb/user-data.txt - wb: [384] 0 bytes
  2015-06-25 21:41:02,184 - util.py[DEBUG]: Writing to /var/lib/cloud/instances/65c9fb0c-0700-4f87-a22f-c59534e98dfb/user-data.txt.i - wb: [384] 345 bytes
  2015-06-25 21:41:02,185 - util.py[DEBUG]: Writing to /var/lib/cloud/instances/65c9fb0c-0700-4f87-a22f-c59534e98dfb/vendor-data.txt - wb: [384] 234 bytes
  2015-06-25 21:41:02,185 - util.py[DEBUG]: Reading from /proc/uptime (quiet=False)

  After following the call chain all the way down, I found the
  problematic code in user_data.py:

  # Coverts a raw string into a mime message
  def convert_string(raw_data, headers=None):
      if not raw_data:
          raw_data = ''
      if not headers:
          headers = {}
      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():
              _replace_header(msg, key, val)
      else:
          mtype = headers.get(CONTENT_TYPE, NOT_MULTIPART_TYPE)
          maintype, subtype = mtype.split("/", 1)
          msg = MIMEBase(maintype, subtype, *headers)
          msg.set_payload(data)
      return msg

  raw_data in the case that is failing is a dictionary rather than the
  expected string, so slicing into data causes a TypeError: unhashable
  type exception.

  I think this bug was fixed after a fashion in 0.7.7, where the call to
  util.decomp_gzip() is now wrapped by util.decode_binary(), which
  appears to always return a string.

To manage notifications about this bug go to:
https://bugs.launchpad.net/cloud-init/+bug/1469260/+subscriptions


Follow ups

References