diff options
author | David Shrewsbury <dshrewsb@redhat.com> | 2019-05-31 10:34:42 -0400 |
---|---|---|
committer | David Shrewsbury <dshrewsb@redhat.com> | 2019-09-16 10:47:27 -0400 |
commit | e1460154d942cb9da05c39757e664899bb5bfaa8 (patch) | |
tree | 84ce12d68e9b7b4c15121219509d8dd86471b80f | |
parent | f6b6991af29d18f5454c579aeef1f2297e6ba335 (diff) | |
download | zuul-e1460154d942cb9da05c39757e664899bb5bfaa8.tar.gz |
Add autohold-info CLI command
New command for the zuul CLI client to retrieve autohold details.
Currently, the only new information included is the 'current_count'
field, but this will later be extended to include held nodes.
Change-Id: Ieae2aea73123b5467d825d4738be07481bb15348
-rw-r--r-- | doc/source/admin/client.rst | 8 | ||||
-rw-r--r-- | releasenotes/notes/autohold-info-940288df947d5091.yaml | 5 | ||||
-rw-r--r-- | tests/unit/test_scheduler.py | 29 | ||||
-rwxr-xr-x | zuul/cmd/client.py | 27 | ||||
-rw-r--r-- | zuul/rpcclient.py | 8 | ||||
-rw-r--r-- | zuul/rpclistener.py | 11 | ||||
-rw-r--r-- | zuul/scheduler.py | 17 |
7 files changed, 105 insertions, 0 deletions
diff --git a/doc/source/admin/client.rst b/doc/source/admin/client.rst index 0a55724e8..1fec75be5 100644 --- a/doc/source/admin/client.rst +++ b/doc/source/admin/client.rst @@ -47,6 +47,14 @@ Example:: zuul autohold-delete --id 0000000123 +Autohold Info +^^^^^^^^^^^^^ +.. program-output:: zuul autohold-info --help + +Example:: + + zuul autohold-info --id 0000000123 + Autohold List ^^^^^^^^^^^^^ .. program-output:: zuul autohold-list --help diff --git a/releasenotes/notes/autohold-info-940288df947d5091.yaml b/releasenotes/notes/autohold-info-940288df947d5091.yaml new file mode 100644 index 000000000..2ae2de7aa --- /dev/null +++ b/releasenotes/notes/autohold-info-940288df947d5091.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + A new zuul CLI command, autohold-info, has been added to retrieve full + details for an existing autohold request. diff --git a/tests/unit/test_scheduler.py b/tests/unit/test_scheduler.py index 42ff2e430..dd73dd8b1 100644 --- a/tests/unit/test_scheduler.py +++ b/tests/unit/test_scheduler.py @@ -1717,6 +1717,35 @@ class TestScheduler(ZuulTestCase): self.assertEqual(request2.current_count, request3.current_count) @simple_layout('layouts/autohold.yaml') + def test_autohold_info(self): + client = zuul.rpcclient.RPCClient('127.0.0.1', + self.gearman_server.port) + self.addCleanup(client.shutdown) + + # Empty dict should be returned for "not found" + request = client.autohold_info("XxXxX") + self.assertEqual({}, request) + + r = client.autohold('tenant-one', 'org/project', 'project-test2', + "", "", "reason text", 1) + self.assertTrue(r) + + # There should be a record in ZooKeeper + request_list = self.zk.getHoldRequests() + self.assertEqual(1, len(request_list)) + request = self.zk.getHoldRequest(request_list[0]) + self.assertIsNotNone(request) + + request = client.autohold_info(request.id) + self.assertNotEqual({}, request) + self.assertEqual('tenant-one', request['tenant']) + self.assertEqual('review.example.com/org/project', request['project']) + self.assertEqual('project-test2', request['job']) + self.assertEqual('reason text', request['reason']) + self.assertEqual(1, request['max_count']) + self.assertEqual(0, request['current_count']) + + @simple_layout('layouts/autohold.yaml') def test_autohold_delete(self): client = zuul.rpcclient.RPCClient('127.0.0.1', self.gearman_server.port) diff --git a/zuul/cmd/client.py b/zuul/cmd/client.py index 2a1ec1c65..e8f457966 100755 --- a/zuul/cmd/client.py +++ b/zuul/cmd/client.py @@ -214,6 +214,13 @@ class Client(zuul.cmd.ZuulApp): help='request ID', required=True) + cmd_autohold_info = subparsers.add_parser( + 'autohold-info', help='retrieve autohold request detailed info') + cmd_autohold_info.set_defaults(func=self.autohold_info) + cmd_autohold_info.add_argument('--id', + help='request ID', + required=True) + cmd_autohold_list = subparsers.add_parser( 'autohold-list', help='list autohold requests') cmd_autohold_list.add_argument('--tenant', help='tenant name', @@ -446,6 +453,26 @@ class Client(zuul.cmd.ZuulApp): client = self.get_client() return client.autohold_delete(self.args.id) + def autohold_info(self): + client = self.get_client() + request = client.autohold_info(self.args.id) + + if not request: + print("Autohold request not found") + return True + + print("ID: %s" % request['id']) + print("Tenant: %s" % request['tenant']) + print("Project: %s" % request['project']) + print("Job: %s" % request['job']) + print("Ref Filter: %s" % request['ref_filter']) + print("Max Count: %s" % request['max_count']) + print("Current Count: %s" % request['current_count']) + print("Node Expiration: %s" % request['node_expiration']) + print("Reason: %s" % request['reason']) + + return True + def autohold_list(self): client = self.get_client() autohold_requests = client.autohold_list(tenant=self.args.tenant) diff --git a/zuul/rpcclient.py b/zuul/rpcclient.py index 45417a805..0579dcc94 100644 --- a/zuul/rpcclient.py +++ b/zuul/rpcclient.py @@ -66,6 +66,14 @@ class RPCClient(object): data = {'request_id': request_id} return not self.submitJob('zuul:autohold_delete', data).failure + def autohold_info(self, request_id): + data = {'request_id': request_id} + job = self.submitJob('zuul:autohold_info', data) + if job.failure: + return False + else: + return json.loads(job.data[0]) + # todo allow filtering per tenant, like in the REST API def autohold_list(self, *args, **kwargs): data = {} diff --git a/zuul/rpclistener.py b/zuul/rpclistener.py index eecf559e3..4035127f0 100644 --- a/zuul/rpclistener.py +++ b/zuul/rpclistener.py @@ -35,6 +35,7 @@ class RPCListener(object): functions = [ 'autohold', 'autohold_delete', + 'autohold_info', 'autohold_list', 'allowed_labels_get', 'dequeue', @@ -93,6 +94,16 @@ class RPCListener(object): return job.sendWorkComplete() + def handle_autohold_info(self, job): + args = json.loads(job.arguments) + request_id = args['request_id'] + try: + data = self.sched.autohold_info(request_id) + except Exception as e: + job.sendWorkException(str(e).encode('utf8')) + return + job.sendWorkComplete(json.dumps(data)) + def handle_autohold_delete(self, job): args = json.loads(job.arguments) request_id = args['request_id'] diff --git a/zuul/scheduler.py b/zuul/scheduler.py index ee89c08bb..b525584af 100644 --- a/zuul/scheduler.py +++ b/zuul/scheduler.py @@ -580,6 +580,23 @@ class Scheduler(threading.Thread): data.append(request.toDict()) return data + def autohold_info(self, hold_request_id): + ''' + Get autohold request details. + + :param str hold_request_id: The unique ID of the request to delete. + ''' + try: + hold_request = self.zk.getHoldRequest(hold_request_id) + except Exception: + self.log.exception( + "Error retrieving autohold ID %s:", hold_request_id) + return {} + + if hold_request is None: + return {} + return hold_request.toDict() + def autohold_delete(self, hold_request_id): ''' Delete an autohold request. |