Do not error out on empty cloud-config

If a cloud-config content is empty or it contains
a comment, cloudbase-init will error out.

This commit addresses this failure by throwing a
CloudConfigError that is caught later in the
execution chain.

Change-Id: Ifd209ca362e62b2fc6ce4e631fc9e77da8aca745
This commit is contained in:
Adrian Vladu 2017-06-20 14:12:07 +03:00
parent 43cef17976
commit 8b6e7a4c84
2 changed files with 23 additions and 22 deletions

View File

@ -61,10 +61,9 @@ class CloudConfigPluginExecutor(object):
try:
content = yaml.load(stream, Loader=loader)
except (TypeError, ValueError, AttributeError):
msg = "Invalid yaml stream provided."
LOG.error(msg)
raise CloudConfigError(msg)
raise CloudConfigError("Invalid yaml stream provided.")
if not content:
raise CloudConfigError("Empty yaml stream provided.")
return cls(**content)
def execute(self):
@ -99,8 +98,9 @@ class CloudConfigPlugin(base.BaseUserDataPlugin):
"""
try:
executor = CloudConfigPluginExecutor.from_yaml(part)
except CloudConfigError:
LOG.error("Could not process the type %r", type(part))
except CloudConfigError as ex:
LOG.error('Could not process part type %(type)r: %(err)r',
{'type': type(part), 'err': str(ex)})
else:
return executor.execute()

View File

@ -52,25 +52,26 @@ class CloudConfigPluginTests(unittest.TestCase):
CONF.cloud_config_plugins = orig
def test_executor_from_yaml(self):
expected_logging = ["Invalid yaml stream provided."]
for invalid in (mock.sentinel.yaml, None, 1, int):
with testutils.LogSnatcher('cloudbaseinit.plugins.'
'common.userdataplugins.'
'cloudconfig') as snatcher:
with self.assertRaises(cloudconfig.CloudConfigError) as cm:
cloudconfig.CloudConfigPluginExecutor.from_yaml(invalid)
self.assertEqual(expected_logging, snatcher.output)
self.assertEqual("Invalid yaml stream provided.",
str(cm.exception))
for invalid in (mock.sentinel.yaml, None, 1, int, '{}'):
with self.assertRaises(cloudconfig.CloudConfigError):
cloudconfig.CloudConfigPluginExecutor.from_yaml(invalid)
executor = cloudconfig.CloudConfigPluginExecutor.from_yaml('{}')
executor = cloudconfig.CloudConfigPluginExecutor.from_yaml('{f: 1}')
self.assertIsInstance(executor, cloudconfig.CloudConfigPluginExecutor)
def test_invalid_type(self):
def _test_invalid_type(self, part, err_msg):
with testutils.LogSnatcher('cloudbaseinit.plugins.common.'
'userdataplugins.cloudconfig') as snatcher:
self.plugin.process_non_multipart({'unsupported'})
self.plugin.process_non_multipart(part)
expected = ["Invalid yaml stream provided.",
"Could not process the type %r" % set]
self.assertEqual(expected, snatcher.output)
expected = ("Could not process part type %(type)r: %(err)r"
% {'type': type(part), 'err': err_msg})
self.assertEqual([expected], snatcher.output)
def test_invalid_type(self):
self._test_invalid_type({'unsupported'},
"Invalid yaml stream provided.")
def test_invalid_type_empty(self):
self._test_invalid_type('#comment',
'Empty yaml stream provided.')