From 715e5d4f51a3dc38f08c0c3ce65d6a2e2247981a Mon Sep 17 00:00:00 2001 From: Steven Dake Date: Thu, 1 Aug 2013 18:05:05 -0700 Subject: [PATCH] Revert "Replace part_handler.py with write-files cloudinit mechanism" Ubuntu has 0.6 of cloudinit, and write-files doesn't work on that distro. Ubuntu does not intend to update cloudinit in their LTS release to 0.7. This reverts commit 621f5bfdbab46498b37cdc4865afa57e0f0498e0. Fixes: Bug #1207088 Change-Id: If80863883afee28bdde6dd506826ec5710cc0308 --- heat/cloudinit/boothook.sh | 1 - heat/cloudinit/config | 2 - heat/cloudinit/loguserdata.py | 1 + heat/cloudinit/part_handler.py | 46 +++++++++++++++++++ heat/engine/resources/instance.py | 75 +++++++++++-------------------- heat/tests/test_loguserdata.py | 6 +++ 6 files changed, 78 insertions(+), 53 deletions(-) create mode 100644 heat/cloudinit/part_handler.py diff --git a/heat/cloudinit/boothook.sh b/heat/cloudinit/boothook.sh index b15ed41cba..f7d46a7f53 100755 --- a/heat/cloudinit/boothook.sh +++ b/heat/cloudinit/boothook.sh @@ -2,7 +2,6 @@ setenforce 0 useradd -m @INSTANCE_USER@ echo -e '@INSTANCE_USER@\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers -mkdir /var/lib/heat-cfntools # Do not remove - the cloud boothook should always return success exit 0 diff --git a/heat/cloudinit/config b/heat/cloudinit/config index bf94162e02..bd363f89b5 100644 --- a/heat/cloudinit/config +++ b/heat/cloudinit/config @@ -1,4 +1,3 @@ -#cloud-config user: @INSTANCE_USER@ cloud_config_modules: @@ -7,7 +6,6 @@ cloud_config_modules: - timezone - update_etc_hosts - update_hostname - - write-files # Capture all subprocess output into a logfile # Useful for troubleshooting cloud-init issues diff --git a/heat/cloudinit/loguserdata.py b/heat/cloudinit/loguserdata.py index 024d80f09a..267098ffac 100755 --- a/heat/cloudinit/loguserdata.py +++ b/heat/cloudinit/loguserdata.py @@ -78,6 +78,7 @@ def main(): return -1 userdata_path = os.path.join(VAR_PATH, 'cfn-userdata') + os.chmod(userdata_path, 0o700) LOG.info('Provision began: %s\n' % datetime.datetime.now()) returncode = call([userdata_path]) diff --git a/heat/cloudinit/part_handler.py b/heat/cloudinit/part_handler.py new file mode 100644 index 0000000000..64a24b470e --- /dev/null +++ b/heat/cloudinit/part_handler.py @@ -0,0 +1,46 @@ +#part-handler + +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import datetime +import errno +import os + + +def list_types(): + return(["text/x-cfninitdata"]) + + +def handle_part(data, ctype, filename, payload): + if ctype == "__begin__": + try: + os.makedirs('/var/lib/heat-cfntools', 0o700) + except OSError as e: + if e.errno != errno.EEXIST: + raise + return + + 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': + with open('/var/lib/heat-cfntools/%s' % filename, 'w') as f: + f.write(payload) + + # TODO(sdake) hopefully temporary until users move to heat-cfntools-1.3 + 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 b8a2c980bd..0ef36e69e7 100644 --- a/heat/engine/resources/instance.py +++ b/heat/engine/resources/instance.py @@ -19,7 +19,6 @@ import json import os import pkgutil from urlparse import urlparse -import yaml from oslo.config import cfg @@ -211,33 +210,30 @@ class Instance(resource.Resource): filename=filename) return msg - def read_cfg_file(): - rd = pkgutil.get_data('heat', 'cloudinit/config') - rd = rd.replace('@INSTANCE_USER@', - cfg.CONF.instance_user) - rd = yaml.safe_load(rd) - return rd - - def add_data_file(fn, data): - rd = [{'owner': 'root:root', - 'path': '/var/lib/heat-cfntools/%s' % fn, - 'permissions': '0700', - 'content': '%s' % data}] - return rd - - def yaml_add(yd, fn, data): - rd = '%s%s' % (yd, yaml.safe_dump(add_data_file(fn, data))) - return rd - - def read_data_file(fn): - data = pkgutil.get_data('heat', 'cloudinit/%s' % fn) - rd = add_data_file(fn, data) - return rd - def read_cloudinit_file(fn): - rd = pkgutil.get_data('heat', 'cloudinit/%s' % fn) - rd = rd.replace('@INSTANCE_USER@', cfg.CONF.instance_user) - return rd + data = pkgutil.get_data('heat', 'cloudinit/%s' % fn) + data = data.replace('@INSTANCE_USER@', + cfg.CONF.instance_user) + return data + + attachments = [(read_cloudinit_file('config'), 'cloud-config'), + (read_cloudinit_file('boothook.sh'), 'boothook.sh', + 'cloud-boothook'), + (read_cloudinit_file('part_handler.py'), + 'part-handler.py'), + (userdata, 'cfn-userdata', 'x-cfninitdata'), + (read_cloudinit_file('loguserdata.py'), + 'loguserdata.py', 'x-shellscript')] + + if 'Metadata' in self.t: + attachments.append((json.dumps(self.metadata), + 'cfn-init-data', 'x-cfninitdata')) + + attachments.append((cfg.CONF.heat_watch_server_url, + 'cfn-watch-server', 'x-cfninitdata')) + + attachments.append((cfg.CONF.heat_metadata_server_url, + 'cfn-metadata-server', 'x-cfninitdata')) # Create a boto config which the cfntools on the host use to know # where the cfn and cw API's are to be accessed @@ -255,30 +251,9 @@ class Instance(resource.Resource): "cloudwatch_region_name = heat", "cloudwatch_region_endpoint = %s" % cw_url.hostname]) + attachments.append((boto_cfg, + 'cfn-boto-cfg', 'x-cfninitdata')) - # Build yaml write_files section - yamld = '' - yamld = yaml_add(yamld, 'cfn-watch-server', - cfg.CONF.heat_watch_server_url) - yamld = yaml_add(yamld, 'cfn-metadata-server', - cfg.CONF.heat_metadata_server_url) - yamld = yaml_add(yamld, 'cfn-boto-cfg', - boto_cfg) - yamld = yaml_add(yamld, 'cfn-userdata', - userdata) - - if 'Metadata' in self.t: - yamld = yaml_add(yamld, 'cfn-init-data', - json.dumps(self.metadata)) - - yamld = "%swrite_files:\n%s" % (yaml.safe_dump(read_cfg_file()), - yamld) - - attachments = [(yamld, 'cloud-config'), - (read_cloudinit_file('boothook.sh'), 'boothook.sh', - 'cloud-boothook'), - (read_cloudinit_file('loguserdata.py'), - 'x-shellscript')] subparts = [make_subpart(*args) for args in attachments] mime_blob = MIMEMultipart(_subparts=subparts) diff --git a/heat/tests/test_loguserdata.py b/heat/tests/test_loguserdata.py index ec659dab1e..e9919983e1 100644 --- a/heat/tests/test_loguserdata.py +++ b/heat/tests/test_loguserdata.py @@ -44,6 +44,7 @@ class LoguserdataTest(HeatTestCase): super(LoguserdataTest, self).setUp() self.m.StubOutWithMock(pkg_resources, 'get_distribution') self.m.StubOutWithMock(subprocess, 'Popen') + self.m.StubOutWithMock(os, 'chmod') def test_ci_version(self): # too old versions @@ -89,6 +90,7 @@ class LoguserdataTest(HeatTestCase): pkg_resources.get_distribution('cloud-init').AndReturn( FakeCiVersion('0.7.0')) + os.chmod('/var/lib/heat-cfntools/cfn-userdata', 0o700).AndReturn(None) subprocess.Popen( ['/var/lib/heat-cfntools/cfn-userdata'], stderr=mox.IgnoreArg(), @@ -103,6 +105,7 @@ class LoguserdataTest(HeatTestCase): pkg_resources.get_distribution('cloud-init').AndReturn( FakeCiVersion('0.7.0')) + os.chmod('/var/lib/heat-cfntools/cfn-userdata', 0o700).AndReturn(None) subprocess.Popen( ['/var/lib/heat-cfntools/cfn-userdata'], stderr=mox.IgnoreArg(), @@ -119,6 +122,7 @@ class LoguserdataTest(HeatTestCase): pkg_resources.get_distribution('cloud-init').AndReturn( FakeCiVersion('0.7.0')) + os.chmod('/var/lib/heat-cfntools/cfn-userdata', 0o700).AndReturn(None) subprocess.Popen( ['/var/lib/heat-cfntools/cfn-userdata'], stderr=mox.IgnoreArg(), @@ -133,6 +137,7 @@ class LoguserdataTest(HeatTestCase): def test_main_error_other(self): pkg_resources.get_distribution('cloud-init').AndReturn( FakeCiVersion('0.7.0')) + os.chmod('/var/lib/heat-cfntools/cfn-userdata', 0o700).AndReturn(None) subprocess.Popen( ['/var/lib/heat-cfntools/cfn-userdata'], stderr=mox.IgnoreArg(), @@ -151,6 +156,7 @@ class LoguserdataTest(HeatTestCase): pkg_resources.get_distribution('cloud-init').AndReturn( FakeCiVersion('0.7.0')) + os.chmod('/var/lib/heat-cfntools/cfn-userdata', 0o700).AndReturn(None) subprocess.Popen( ['/var/lib/heat-cfntools/cfn-userdata'], stderr=mox.IgnoreArg(),