From fdc3711c9521a60c9d9cf20aec82ce490bd42050 Mon Sep 17 00:00:00 2001 From: Gorka Eguileor Date: Wed, 4 Nov 2020 11:32:11 +0100 Subject: [PATCH] Fix cinder-manage traceback Running the cinder-manage command with a category but without an action will throw a Traceback saying "oslo_config.cfg.NoSuchOptError: no such option action_fn in group [DEFAULT]" Example command that triggers this: cinder-manage backup This patch fixes this by simulating that the user had used the --help action while still exitting with an error (after all the call was missing arguments). New output: $ cinder-manage backup usage: cinder-manage backup [-h] {list,update_backup_host} ... positional arguments: {list,update_backup_host} optional arguments: -h, --help show this help message and exit Closes-Bug: #1902852 Change-Id: I6fca54d95b41d189545789c775e23223abb37c1b --- cinder/cmd/manage.py | 8 ++++++++ cinder/tests/unit/test_cmd.py | 13 +++++++++++++ .../fix-manage-no-action-46b023476e8cd938.yaml | 7 +++++++ 3 files changed, 28 insertions(+) create mode 100644 releasenotes/notes/fix-manage-no-action-46b023476e8cd938.yaml diff --git a/cinder/cmd/manage.py b/cinder/cmd/manage.py index 2a9cc0081fa..3149300132f 100644 --- a/cinder/cmd/manage.py +++ b/cinder/cmd/manage.py @@ -691,12 +691,20 @@ def methods_of(obj): return result +def missing_action(help_func): + def wrapped(): + help_func() + exit(2) + return wrapped + + def add_command_parsers(subparsers): for category in sorted(CATEGORIES): command_object = CATEGORIES[category]() parser = subparsers.add_parser(category) parser.set_defaults(command_object=command_object) + parser.set_defaults(action_fn=missing_action(parser.print_help)) category_subparsers = parser.add_subparsers(dest='action') diff --git a/cinder/tests/unit/test_cmd.py b/cinder/tests/unit/test_cmd.py index eb3f27e490e..b9f2a1482a5 100644 --- a/cinder/tests/unit/test_cmd.py +++ b/cinder/tests/unit/test_cmd.py @@ -1155,6 +1155,19 @@ class TestCinderManageCmd(test.TestCase): self.assertTrue(register_cli_opt.called) self.assertEqual(2, exit.code) + def test_main_missing_action(self): + sys.argv = ['cinder-manage', 'backup'] + cinder_manage.CONF = cfg.ConfigOpts() + + stdout = io.StringIO() + with mock.patch('sys.stdout', new=stdout): + exit = self.assertRaises(SystemExit, cinder_manage.main) + self.assertEqual(2, exit.code) + + stdout.seek(0) + output = stdout.read() + self.assertTrue(output.startswith('usage: ')) + @mock.patch('oslo_config.cfg.ConfigOpts.__call__') @mock.patch('oslo_log.log.setup') @mock.patch('oslo_config.cfg.ConfigOpts.register_cli_opt') diff --git a/releasenotes/notes/fix-manage-no-action-46b023476e8cd938.yaml b/releasenotes/notes/fix-manage-no-action-46b023476e8cd938.yaml new file mode 100644 index 00000000000..4bf5a38927d --- /dev/null +++ b/releasenotes/notes/fix-manage-no-action-46b023476e8cd938.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + `Bug #1902852 + `_: + Fixed throwing Python traceback message when using ``cinder-manage + `` without an action for the category.