summaryrefslogtreecommitdiff
path: root/heat_cfntools
diff options
context:
space:
mode:
authorSimon Pasquier <simon.pasquier@bull.net>2014-01-16 11:16:13 +0100
committerSimon Pasquier <simon.pasquier@bull.net>2014-02-24 13:36:05 +0100
commit3a0993210d7d08392d97903589cf8adba6fb92d2 (patch)
treed95ad0efd9fc454d3b10828c5afadcc2e9c8c882 /heat_cfntools
parenta61e2219504101ac487c0266d51422b03a766111 (diff)
downloadheat-cfntools-3a0993210d7d08392d97903589cf8adba6fb92d2.tar.gz
Support of ignoreErrors for commands
cfn-init will now fail immediately if a command with the key ignoreErrors='false' or without that key fails (eg it returns an exit code other than 0). This is similar to what the AWS cfn-init script is doing. Change-Id: I41bfa36154fa8b16541a6abb489495739b772376 Closes-Bug: #1269476
Diffstat (limited to 'heat_cfntools')
-rw-r--r--heat_cfntools/cfntools/cfn_helper.py16
-rw-r--r--heat_cfntools/tests/test_cfn_helper.py65
2 files changed, 62 insertions, 19 deletions
diff --git a/heat_cfntools/cfntools/cfn_helper.py b/heat_cfntools/cfntools/cfn_helper.py
index 9579194..4c184cd 100644
--- a/heat_cfntools/cfntools/cfn_helper.py
+++ b/heat_cfntools/cfntools/cfn_helper.py
@@ -829,6 +829,10 @@ def metadata_server_port(
return None
+class CommandsHandlerRunError(Exception):
+ pass
+
+
class CommandsHandler(object):
def __init__(self, commands):
@@ -887,14 +891,12 @@ class CommandsHandler(object):
if command_status == 0:
LOG.info("%s has been successfully executed" % command_label)
else:
- if "ignoreErrors" in properties:
- if properties["ignoreErrors"] == "false":
- LOG.error("%s has failed. Not ignoring" % command_label)
- else:
- LOG.info("%s has failed. Explicit ignoring"
- % command_label)
+ if "ignoreErrors" in properties and \
+ to_boolean(properties["ignoreErrors"]):
+ LOG.info("%s has failed (status=%d). Explicit ignoring"
+ % (command_label, command_status))
else:
- LOG.error("%s has failed." % command_label)
+ raise CommandsHandlerRunError("%s has failed." % command_label)
class GroupsHandler(object):
diff --git a/heat_cfntools/tests/test_cfn_helper.py b/heat_cfntools/tests/test_cfn_helper.py
index 9073d01..e81b9bf 100644
--- a/heat_cfntools/tests/test_cfn_helper.py
+++ b/heat_cfntools/tests/test_cfn_helper.py
@@ -800,18 +800,6 @@ class TestMetadataRetrieve(testtools.TestCase):
finally:
m.UnsetStubs()
- def test_cfn_init(self):
-
- with tempfile.NamedTemporaryFile(mode='w+') as foo_file:
- md_data = {"AWS::CloudFormation::Init": {"config": {"files": {
- foo_file.name: {"content": "bar"}}}}}
-
- md = cfn_helper.Metadata('teststack', None)
- self.assertTrue(
- md.retrieve(meta_str=md_data, last_path=self.last_file))
- md.cfn_init()
- self.assertThat(foo_file.name, ttm.FileContains('bar'))
-
def test_nova_meta_with_cache(self):
meta_in = {"uuid": "f9431d18-d971-434d-9044-5b38f5b4646f",
"availability_zone": "nova",
@@ -960,6 +948,59 @@ class TestMetadataRetrieve(testtools.TestCase):
self.m.VerifyAll()
+class TestCfnInit(MockPopenTestCase):
+
+ def setUp(self):
+ super(TestCfnInit, self).setUp()
+ self.tdir = self.useFixture(fixtures.TempDir())
+ self.last_file = os.path.join(self.tdir.path, 'last_metadata')
+
+ def test_cfn_init(self):
+
+ with tempfile.NamedTemporaryFile(mode='w+') as foo_file:
+ md_data = {"AWS::CloudFormation::Init": {"config": {"files": {
+ foo_file.name: {"content": "bar"}}}}}
+
+ md = cfn_helper.Metadata('teststack', None)
+ self.assertTrue(
+ md.retrieve(meta_str=md_data, last_path=self.last_file))
+ md.cfn_init()
+ self.assertThat(foo_file.name, ttm.FileContains('bar'))
+
+ def test_cfn_init_with_ignore_errors_false(self):
+ self.mock_cmd_run(['su', 'root', '-c', '/bin/command1']).AndReturn(
+ FakePOpen('Doing something', 'error', -1))
+ self.m.ReplayAll()
+
+ md_data = {"AWS::CloudFormation::Init": {"config": {"commands": {
+ "00_foo": {"command": "/bin/command1",
+ "ignoreErrors": "false"}}}}}
+
+ md = cfn_helper.Metadata('teststack', None)
+ self.assertTrue(
+ md.retrieve(meta_str=md_data, last_path=self.last_file))
+ self.assertRaises(cfn_helper.CommandsHandlerRunError, md.cfn_init)
+
+ def test_cfn_init_with_ignore_errors_true(self):
+ self.mock_cmd_run(['su', 'root', '-c', '/bin/command1']).AndReturn(
+ FakePOpen('Doing something', 'error', -1))
+ self.mock_cmd_run(['su', 'root', '-c', '/bin/command2']).AndReturn(
+ FakePOpen('All good'))
+ self.m.ReplayAll()
+
+ md_data = {"AWS::CloudFormation::Init": {"config": {"commands": {
+ "00_foo": {"command": "/bin/command1",
+ "ignoreErrors": "true"},
+ "01_bar": {"command": "/bin/command2",
+ "ignoreErrors": "false"}
+ }}}}
+
+ md = cfn_helper.Metadata('teststack', None)
+ self.assertTrue(
+ md.retrieve(meta_str=md_data, last_path=self.last_file))
+ md.cfn_init()
+
+
class TestSourcesHandler(MockPopenTestCase):
def test_apply_sources_empty(self):
sh = cfn_helper.SourcesHandler({})