summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Smith <chad.smith@canonical.com>2017-08-23 18:54:01 -0600
committerScott Moser <smoser@ubuntu.com>2017-08-25 14:41:55 -0700
commit89579a68d9f51e51b24f96b933da656afd83edfb (patch)
treeeb274c56ed202b5729d8da9f8798271c652778d1
parent44773a480d8fe32e97da44afd01e5882a480d136 (diff)
downloadvyos-cloud-init-89579a68d9f51e51b24f96b933da656afd83edfb.tar.gz
vyos-cloud-init-89579a68d9f51e51b24f96b933da656afd83edfb.zip
cli: Fix command line parsing of coniditionally loaded subcommands.
In an effort to save file load cost during system boot, certain subcommands, analyze and devel, do not get loaded unless the subcommand is specified on the commandline. Because setup.py entrypoint for cloud-init script doesn't specify sysv_args parameter when calling the CLI's main() we need main to read sys.argv into sysv_args so our subparser loading continues to work. LP: #1712676
-rw-r--r--cloudinit/cmd/main.py9
-rw-r--r--tests/unittests/test_cli.py15
2 files changed, 19 insertions, 5 deletions
diff --git a/cloudinit/cmd/main.py b/cloudinit/cmd/main.py
index 5b467979..68563e0c 100644
--- a/cloudinit/cmd/main.py
+++ b/cloudinit/cmd/main.py
@@ -676,11 +676,10 @@ def main_features(name, args):
def main(sysv_args=None):
- if sysv_args is not None:
- parser = argparse.ArgumentParser(prog=sysv_args[0])
- sysv_args = sysv_args[1:]
- else:
- parser = argparse.ArgumentParser()
+ if not sysv_args:
+ sysv_args = sys.argv
+ parser = argparse.ArgumentParser(prog=sysv_args[0])
+ sysv_args = sysv_args[1:]
# Top level args
parser.add_argument('--version', '-v', action='version',
diff --git a/tests/unittests/test_cli.py b/tests/unittests/test_cli.py
index 24498802..12f01852 100644
--- a/tests/unittests/test_cli.py
+++ b/tests/unittests/test_cli.py
@@ -70,6 +70,21 @@ class TestCLI(test_helpers.FilesystemMockingTestCase):
self.assertEqual('modules', parseargs.action[0])
self.assertEqual('main_modules', parseargs.action[1].__name__)
+ def test_conditional_subcommands_from_entry_point_sys_argv(self):
+ """Subcommands from entry-point are properly parsed from sys.argv."""
+ expected_errors = [
+ 'usage: cloud-init analyze', 'usage: cloud-init devel']
+ conditional_subcommands = ['analyze', 'devel']
+ # The cloud-init entrypoint calls main without passing sys_argv
+ for subcommand in conditional_subcommands:
+ with mock.patch('sys.argv', ['cloud-init', subcommand]):
+ try:
+ cli.main()
+ except SystemExit as e:
+ self.assertEqual(2, e.code) # exit 2 on proper usage docs
+ for error_message in expected_errors:
+ self.assertIn(error_message, self.stderr.getvalue())
+
def test_analyze_subcommand_parser(self):
"""The subcommand cloud-init analyze calls the correct subparser."""
self._call_main(['cloud-init', 'analyze'])