From: Jeff Peeler Date: Mon, 7 Jan 2013 17:36:20 +0000 (-0500) Subject: Handle different cloud-init versions gracefully X-Git-Tag: 2014.1~1023 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=93c3d93ec481d81e97d4b120384b5e1d93ca6532;p=openstack-build%2Fheat-build.git Handle different cloud-init versions gracefully Change loguserdata script to python to allow easy detection of which version of cloud-init installed. Some logging was added to part-handler. Took out injecting the command to touch provision-finished in the user data. This is now handled in loguserdata.py. Note that up until cloud-init version 0.6.0, the user data is not passed to part-handler. This behavior is why it's not possible to log the provisioning process with older versions. (Technically could rely on the redirection support added post 0.6.0, but having a separate file just for provisioning seems beneficial.) fixes bug 1072921 Change-Id: I9005a21bfb74f27208f9195a6e10e1d2b474e91f Signed-off-by: Jeff Peeler --- diff --git a/MANIFEST.in b/MANIFEST.in index 36315754..6a99f45b 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -9,7 +9,7 @@ include babel.cfg install.sh run_tests.sh tox.ini uninstall.sh graft templates include heat/versioninfo include heat/cloudinit/config -include heat/cloudinit/loguserdata.sh +include heat/cloudinit/loguserdata.py include heat/cloudinit/part-handler.py include heat/db/sqlalchemy/migrate_repo/migrate.cfg include heat/db/sqlalchemy/migrate_repo/README diff --git a/heat/cloudinit/loguserdata.py b/heat/cloudinit/loguserdata.py new file mode 100644 index 00000000..b5a22466 --- /dev/null +++ b/heat/cloudinit/loguserdata.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +import cloudinit +import sys +import os +import stat +import subprocess +import datetime + +path = None + +try: + path = cloudinit.get_cpath('data') +except AttributeError: + # pre 0.6.0 - user data executed via cloudinit, not this helper + with open('/var/log/heat-provision.log', 'w') as log: + log.write('Unable to log provisioning, need a newer version of' + ' cloud-init\n') + sys.exit(0) + +os.chmod(path + '/cfn-userdata', stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) + +with open('/var/log/heat-provision.log', 'w') as log: + log.write('Provision began: %s\n' % datetime.datetime.now()) + log.flush() + p = subprocess.Popen(path + '/cfn-userdata', stdout=log, stderr=log) + p.wait() + log.write('Provision done: %s\n' % datetime.datetime.now()) + if p.returncode: + sys.exit(p.returncode) + +with open(cloudinit.get_ipath_cur() + '/provision-finished', 'w') as log: + log.write('%s\n' % datetime.datetime.now()) diff --git a/heat/cloudinit/loguserdata.sh b/heat/cloudinit/loguserdata.sh deleted file mode 100755 index 1a54dfff..00000000 --- a/heat/cloudinit/loguserdata.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -chmod +x /var/lib/cloud/data/cfn-userdata -script -f -c /var/lib/cloud/data/cfn-userdata /var/log/heat-provision.log diff --git a/heat/cloudinit/part-handler.py b/heat/cloudinit/part-handler.py index bf52efba..978566c7 100644 --- a/heat/cloudinit/part-handler.py +++ b/heat/cloudinit/part-handler.py @@ -1,5 +1,7 @@ #part-handler +import datetime + def list_types(): return(["text/x-cfninitdata"]) @@ -11,7 +13,10 @@ def handle_part(data, ctype, filename, payload): if ctype == "__end__": return + with open('/var/log/part-handler.log', 'a') as log: + timestamp = datetime.datetime.now() + log.write('%s filename:%s, ctype:%s\n' % (timestamp, filename, ctype)) + if ctype == 'text/x-cfninitdata': - f = open('/var/lib/cloud/data/%s' % filename, 'w') - f.write(payload) - f.close() + with open('/var/lib/cloud/data/%s' % filename, 'w') as f: + f.write(payload) diff --git a/heat/engine/resources/instance.py b/heat/engine/resources/instance.py index 5836c3a9..15e17d5f 100644 --- a/heat/engine/resources/instance.py +++ b/heat/engine/resources/instance.py @@ -174,8 +174,8 @@ class Instance(resource.Resource): (read_cloudinit_file('part-handler.py'), 'part-handler.py'), (userdata, 'cfn-userdata', 'x-cfninitdata'), - (read_cloudinit_file('loguserdata.sh'), - 'loguserdata.sh', 'x-shellscript')] + (read_cloudinit_file('loguserdata.py'), + 'loguserdata.py', 'x-shellscript')] if 'Metadata' in self.t: attachments.append((json.dumps(self.metadata), @@ -217,7 +217,6 @@ class Instance(resource.Resource): for sg in self.properties.get('SecurityGroups')] userdata = self.properties['UserData'] or '' - userdata += '\ntouch /var/lib/cloud/instance/provision-finished\n' flavor = self.properties['InstanceType'] key_name = self.properties['KeyName']