diff --git a/stages-fix-tracebacks-if-a-module-stage-is-undefined.patch b/stages-fix-tracebacks-if-a-module-stage-is-undefined.patch new file mode 100644 index 0000000..b969e3c --- /dev/null +++ b/stages-fix-tracebacks-if-a-module-stage-is-undefined.patch @@ -0,0 +1,94 @@ +From fef2616b9876d3d354b0de1a8e753361e52e77b0 Mon Sep 17 00:00:00 2001 +From: Robert Schweikert +Date: Fri, 15 Jun 2018 13:41:21 -0600 +Subject: [PATCH 219/354] stages: fix tracebacks if a module stage is + undefined or empty + +In /etc/cloud/cloud.cfg, users and imagees can configure which modules run +during a specific cloud-init stage by modifying one of the following +lists: cloud_init_modules, cloud_init_modules, cloud_init_final_modules. + +If any of the configured module lists are absent or empty, cloud-init will +emit the same message it already does for existing lists that only contain +modules which are not unsupported on that platform: + +No 'config' modules to run under section 'cloud_config_modules' + +LP: #1770462 +--- + cloudinit/stages.py | 4 +++- + tests/unittests/test_runs/test_simple_run.py | 32 ++++++++++++++++++++++++++-- + 2 files changed, 33 insertions(+), 3 deletions(-) + +diff --git a/cloudinit/stages.py b/cloudinit/stages.py +index 3998cf6..286607b 100644 +--- a/cloudinit/stages.py ++++ b/cloudinit/stages.py +@@ -697,7 +697,9 @@ class Modules(object): + module_list = [] + if name not in self.cfg: + return module_list +- cfg_mods = self.cfg[name] ++ cfg_mods = self.cfg.get(name) ++ if not cfg_mods: ++ return module_list + # Create 'module_list', an array of hashes + # Where hash['mod'] = module name + # hash['freq'] = frequency +diff --git a/tests/unittests/test_runs/test_simple_run.py b/tests/unittests/test_runs/test_simple_run.py +index 762974e..d67c422 100644 +--- a/tests/unittests/test_runs/test_simple_run.py ++++ b/tests/unittests/test_runs/test_simple_run.py +@@ -1,5 +1,6 @@ + # This file is part of cloud-init. See LICENSE file for license information. + ++import copy + import os + + from cloudinit.tests import helpers +@@ -127,8 +128,9 @@ class TestSimpleRun(helpers.FilesystemMockingTestCase): + """run_section forced skipped modules by using unverified_modules.""" + + # re-write cloud.cfg with unverified_modules override +- self.cfg['unverified_modules'] = ['spacewalk'] # Would have skipped +- cloud_cfg = util.yaml_dumps(self.cfg) ++ cfg = copy.deepcopy(self.cfg) ++ cfg['unverified_modules'] = ['spacewalk'] # Would have skipped ++ cloud_cfg = util.yaml_dumps(cfg) + util.ensure_dir(os.path.join(self.new_root, 'etc', 'cloud')) + util.write_file(os.path.join(self.new_root, 'etc', + 'cloud', 'cloud.cfg'), cloud_cfg) +@@ -150,4 +152,30 @@ class TestSimpleRun(helpers.FilesystemMockingTestCase): + "running unverified_modules: 'spacewalk'", + self.logs.getvalue()) + ++ def test_none_ds_run_with_no_config_modules(self): ++ """run_section will report no modules run when none are configured.""" ++ ++ # re-write cloud.cfg with unverified_modules override ++ cfg = copy.deepcopy(self.cfg) ++ # Represent empty configuration in /etc/cloud/cloud.cfg ++ cfg['cloud_init_modules'] = None ++ cloud_cfg = util.yaml_dumps(cfg) ++ util.ensure_dir(os.path.join(self.new_root, 'etc', 'cloud')) ++ util.write_file(os.path.join(self.new_root, 'etc', ++ 'cloud', 'cloud.cfg'), cloud_cfg) ++ ++ initer = stages.Init() ++ initer.read_cfg() ++ initer.initialize() ++ initer.fetch() ++ initer.instancify() ++ initer.update() ++ initer.cloudify().run('consume_data', initer.consume_data, ++ args=[PER_INSTANCE], freq=PER_INSTANCE) ++ ++ mods = stages.Modules(initer) ++ (which_ran, failures) = mods.run_section('cloud_init_modules') ++ self.assertTrue(len(failures) == 0) ++ self.assertEqual([], which_ran) ++ + # vi: ts=4 expandtab +-- +1.7.12.4 +