From aaecb282eea23847cf2d12d6ed90ca89401fe2e9 Mon Sep 17 00:00:00 2001 From: David Shrewsbury Date: Wed, 24 Jan 2018 16:35:35 -0500 Subject: [PATCH] Split out erasing from 'info' command into 'erase' This removes the --erase option from the 'info' command into its own command. Change-Id: I7f75e8efd49644f272102ff65c48d22a878334fe --- doc/source/operation.rst | 5 +++ nodepool/cmd/nodepoolcmd.py | 64 ++++++++++++++++++--------------- nodepool/tests/test_commands.py | 13 ++++--- 3 files changed, 49 insertions(+), 33 deletions(-) diff --git a/doc/source/operation.rst b/doc/source/operation.rst index 01b463f78..6f7cdc309 100644 --- a/doc/source/operation.rst +++ b/doc/source/operation.rst @@ -210,6 +210,11 @@ info .. program-output:: nodepool info --help :nostderr: +erase +^^^^^ +.. program-output:: nodepool erase --help + :nostderr: + If Nodepool's database gets out of sync with reality, the following commands can help identify compute instances or images that are unknown to Nodepool: diff --git a/nodepool/cmd/nodepoolcmd.py b/nodepool/cmd/nodepoolcmd.py index 629788bbf..819c3865e 100755 --- a/nodepool/cmd/nodepoolcmd.py +++ b/nodepool/cmd/nodepoolcmd.py @@ -127,18 +127,23 @@ class NodePoolCmd(NodepoolApp): help='Show provider data from zookeeper') cmd_info.add_argument( 'provider', - help='provider name', + help='Provider name', metavar='PROVIDER') - cmd_info.add_argument( - '--erase', - help='erase ZooKeeper data for this provider', - action='store_true') - cmd_info.add_argument( - '--force', - help='used with --erase to bypass the warning prompt', - action='store_true') cmd_info.set_defaults(func=self.info) + cmd_erase = subparsers.add_parser( + 'erase', + help='Erase provider data from zookeeper') + cmd_erase.add_argument( + 'provider', + help='Provider name', + metavar='PROVIDER') + cmd_erase.add_argument( + '--force', + help='Bypass the warning prompt', + action='store_true') + cmd_erase.set_defaults(func=self.erase) + return parser def setup_logging(self): @@ -302,11 +307,27 @@ class NodePoolCmd(NodepoolApp): self.zk.storeImageUpload(image.image_name, image.build_id, image.provider_name, image, image.id) - def erase(self, provider_name, provider_builds, provider_nodes): - print("\nErasing build data for %s..." % provider_name) - self.zk.removeProviderBuilds(provider_name, provider_builds) - print("Erasing node data for %s..." % provider_name) - self.zk.removeProviderNodes(provider_name, provider_nodes) + def erase(self): + def do_erase(provider_name, provider_builds, provider_nodes): + print("Erasing build data for %s..." % provider_name) + self.zk.removeProviderBuilds(provider_name, provider_builds) + print("Erasing node data for %s..." % provider_name) + self.zk.removeProviderNodes(provider_name, provider_nodes) + + provider_name = self.args.provider + provider_builds = self.zk.getProviderBuilds(provider_name) + provider_nodes = self.zk.getProviderNodes(provider_name) + + if self.args.force: + do_erase(provider_name, provider_builds, provider_nodes) + else: + print("\nWARNING! This action is not reversible!") + answer = input("Erase ZooKeeper data for provider %s? [N/y] " % + provider_name) + if answer.lower() != 'y': + print("Aborting. No data erased.") + else: + do_erase(provider_name, provider_builds, provider_nodes) def info(self): provider_name = self.args.provider @@ -329,19 +350,6 @@ class NodePoolCmd(NodepoolApp): t.add_row([node.id, node.external_id]) print(t) - if self.args.erase: - if self.args.force: - self.erase(provider_name, provider_builds, provider_nodes) - return - - print("\nWARNING! This action is not reversible!") - answer = input("Erase ZooKeeper data for provider %s? [N/y] " % - provider_name) - if answer.lower() != 'y': - print("Aborting. No data erased.") - else: - self.erase(provider_name, provider_builds, provider_nodes) - def config_validate(self): validator = ConfigValidator(self.args.config) validator.validate() @@ -375,7 +383,7 @@ class NodePoolCmd(NodepoolApp): 'image-list', 'dib-image-delete', 'image-delete', 'alien-image-list', 'list', 'hold', 'delete', - 'request-list', 'info'): + 'request-list', 'info', 'erase'): self.zk = zk.ZooKeeper() self.zk.connect(list(config.zookeeper_servers.values())) diff --git a/nodepool/tests/test_commands.py b/nodepool/tests/test_commands.py index 53fbf43bf..46e03fa35 100644 --- a/nodepool/tests/test_commands.py +++ b/nodepool/tests/test_commands.py @@ -301,7 +301,7 @@ class TestNodepoolCMD(tests.DBTestCase): result = nodepoolcmd.main() self.assertEqual(1, result) - def test_info(self): + def test_info_and_erase(self): configfile = self.setup_config('info_cmd_two_provider.yaml') pool = self.useNodepool(configfile, watermark_sleep=1) self.useBuilder(configfile) @@ -321,14 +321,17 @@ class TestNodepoolCMD(tests.DBTestCase): ['info', 'fake-provider2'], 0, 'fake-image', 1) - # Verify that the second provider node is listed. We go ahead - # and erase the data here (after it has been displayed) so that - # we can verify the erase in the next steps. + # Verify that the second provider node is listed. self.assert_listed( configfile, - ['info', 'fake-provider2', '--erase', '--force'], + ['info', 'fake-provider2'], 0, p2_nodes[0].id, 1) + # Erase the data for the second provider + self.patch_argv( + "-c", configfile, 'erase', 'fake-provider2', '--force') + nodepoolcmd.main() + # Verify that no build or node for the second provider is listed # after the previous erase self.assert_listed(