Merge "New client command for printing autohold requests" into feature/zuulv3
diff --git a/tests/unit/test_scheduler.py b/tests/unit/test_scheduler.py
index f2d7c96..9090421 100755
--- a/tests/unit/test_scheduler.py
+++ b/tests/unit/test_scheduler.py
@@ -1515,6 +1515,31 @@
held_nodes += 1
self.assertEqual(held_nodes, 1)
+ @simple_layout('layouts/autohold.yaml')
+ def test_autohold_list(self):
+ client = zuul.rpcclient.RPCClient('127.0.0.1',
+ self.gearman_server.port)
+ self.addCleanup(client.shutdown)
+
+ r = client.autohold('tenant-one', 'org/project', 'project-test2',
+ "reason text", 1)
+ self.assertTrue(r)
+
+ autohold_requests = client.autohold_list()
+ self.assertNotEqual({}, autohold_requests)
+ self.assertEqual(1, len(autohold_requests.keys()))
+
+ # The single dict key should be a CSV string value
+ key = list(autohold_requests.keys())[0]
+ tenant, project, job = key.split(',')
+
+ self.assertEqual('tenant-one', tenant)
+ self.assertIn('org/project', project)
+ self.assertEqual('project-test2', job)
+
+ # Note: the value is converted from set to list by json.
+ self.assertEqual([1, "reason text"], autohold_requests[key])
+
@simple_layout('layouts/three-projects.yaml')
def test_dependent_behind_dequeue(self):
# This particular test does a large amount of merges and needs a little
diff --git a/zuul/cmd/client.py b/zuul/cmd/client.py
index 177283e..c9e399a 100755
--- a/zuul/cmd/client.py
+++ b/zuul/cmd/client.py
@@ -61,6 +61,10 @@
required=False, type=int, default=1)
cmd_autohold.set_defaults(func=self.autohold)
+ cmd_autohold_list = subparsers.add_parser(
+ 'autohold-list', help='list autohold requests')
+ cmd_autohold_list.set_defaults(func=self.autohold_list)
+
cmd_enqueue = subparsers.add_parser('enqueue', help='enqueue a change')
cmd_enqueue.add_argument('--tenant', help='tenant name',
required=True)
@@ -162,6 +166,27 @@
count=self.args.count)
return r
+ def autohold_list(self):
+ client = zuul.rpcclient.RPCClient(
+ self.server, self.port, self.ssl_key, self.ssl_cert, self.ssl_ca)
+ autohold_requests = client.autohold_list()
+
+ if len(autohold_requests.keys()) == 0:
+ print("No autohold requests found")
+ return True
+
+ table = prettytable.PrettyTable(
+ field_names=['Tenant', 'Project', 'Job', 'Count', 'Reason'])
+
+ for key, value in autohold_requests.items():
+ # The key comes to us as a CSV string because json doesn't like
+ # non-str keys.
+ tenant_name, project_name, job_name = key.split(',')
+ count, reason = value
+ table.add_row([tenant_name, project_name, job_name, count, reason])
+ print(table)
+ return True
+
def enqueue(self):
client = zuul.rpcclient.RPCClient(
self.server, self.port, self.ssl_key, self.ssl_cert, self.ssl_ca)
diff --git a/zuul/rpcclient.py b/zuul/rpcclient.py
index 1a0a084..8f2e5dc 100644
--- a/zuul/rpcclient.py
+++ b/zuul/rpcclient.py
@@ -56,6 +56,14 @@
'count': count}
return not self.submitJob('zuul:autohold', data).failure
+ def autohold_list(self):
+ data = {}
+ job = self.submitJob('zuul:autohold_list', data)
+ if job.failure:
+ return False
+ else:
+ return json.loads(job.data[0])
+
def enqueue(self, tenant, pipeline, project, trigger, change):
data = {'tenant': tenant,
'pipeline': pipeline,
diff --git a/zuul/rpclistener.py b/zuul/rpclistener.py
index 52a7e51..11d6684 100644
--- a/zuul/rpclistener.py
+++ b/zuul/rpclistener.py
@@ -50,6 +50,7 @@
def register(self):
self.worker.registerFunction("zuul:autohold")
+ self.worker.registerFunction("zuul:autohold_list")
self.worker.registerFunction("zuul:enqueue")
self.worker.registerFunction("zuul:enqueue_ref")
self.worker.registerFunction("zuul:promote")
@@ -90,6 +91,17 @@
except Exception:
self.log.exception("Exception while getting job")
+ def handle_autohold_list(self, job):
+ req = {}
+
+ # The json.dumps() call cannot handle dict keys that are not strings
+ # so we convert our key to a CSV string that the caller can parse.
+ for key, value in self.sched.autohold_requests.items():
+ new_key = ','.join(key)
+ req[new_key] = value
+
+ job.sendWorkComplete(json.dumps(req))
+
def handle_autohold(self, job):
args = json.loads(job.arguments)
params = {}