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:
parent
43cef17976
commit
8b6e7a4c84
@ -61,10 +61,9 @@ class CloudConfigPluginExecutor(object):
|
|||||||
try:
|
try:
|
||||||
content = yaml.load(stream, Loader=loader)
|
content = yaml.load(stream, Loader=loader)
|
||||||
except (TypeError, ValueError, AttributeError):
|
except (TypeError, ValueError, AttributeError):
|
||||||
msg = "Invalid yaml stream provided."
|
raise CloudConfigError("Invalid yaml stream provided.")
|
||||||
LOG.error(msg)
|
if not content:
|
||||||
raise CloudConfigError(msg)
|
raise CloudConfigError("Empty yaml stream provided.")
|
||||||
|
|
||||||
return cls(**content)
|
return cls(**content)
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
@ -99,8 +98,9 @@ class CloudConfigPlugin(base.BaseUserDataPlugin):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
executor = CloudConfigPluginExecutor.from_yaml(part)
|
executor = CloudConfigPluginExecutor.from_yaml(part)
|
||||||
except CloudConfigError:
|
except CloudConfigError as ex:
|
||||||
LOG.error("Could not process the type %r", type(part))
|
LOG.error('Could not process part type %(type)r: %(err)r',
|
||||||
|
{'type': type(part), 'err': str(ex)})
|
||||||
else:
|
else:
|
||||||
return executor.execute()
|
return executor.execute()
|
||||||
|
|
||||||
|
@ -52,25 +52,26 @@ class CloudConfigPluginTests(unittest.TestCase):
|
|||||||
CONF.cloud_config_plugins = orig
|
CONF.cloud_config_plugins = orig
|
||||||
|
|
||||||
def test_executor_from_yaml(self):
|
def test_executor_from_yaml(self):
|
||||||
expected_logging = ["Invalid yaml stream provided."]
|
for invalid in (mock.sentinel.yaml, None, 1, int, '{}'):
|
||||||
for invalid in (mock.sentinel.yaml, None, 1, int):
|
with self.assertRaises(cloudconfig.CloudConfigError):
|
||||||
with testutils.LogSnatcher('cloudbaseinit.plugins.'
|
cloudconfig.CloudConfigPluginExecutor.from_yaml(invalid)
|
||||||
'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))
|
|
||||||
|
|
||||||
executor = cloudconfig.CloudConfigPluginExecutor.from_yaml('{}')
|
executor = cloudconfig.CloudConfigPluginExecutor.from_yaml('{f: 1}')
|
||||||
self.assertIsInstance(executor, cloudconfig.CloudConfigPluginExecutor)
|
self.assertIsInstance(executor, cloudconfig.CloudConfigPluginExecutor)
|
||||||
|
|
||||||
def test_invalid_type(self):
|
def _test_invalid_type(self, part, err_msg):
|
||||||
with testutils.LogSnatcher('cloudbaseinit.plugins.common.'
|
with testutils.LogSnatcher('cloudbaseinit.plugins.common.'
|
||||||
'userdataplugins.cloudconfig') as snatcher:
|
'userdataplugins.cloudconfig') as snatcher:
|
||||||
self.plugin.process_non_multipart({'unsupported'})
|
self.plugin.process_non_multipart(part)
|
||||||
|
|
||||||
expected = ["Invalid yaml stream provided.",
|
expected = ("Could not process part type %(type)r: %(err)r"
|
||||||
"Could not process the type %r" % set]
|
% {'type': type(part), 'err': err_msg})
|
||||||
self.assertEqual(expected, snatcher.output)
|
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.')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user