Commit a629ecb9 authored by Iustin Pop's avatar Iustin Pop
Browse files

Standardise LUXI call argument types

Currently, we have 4 types of arguments in LUXI calls:

- most common, a list of values
- a single argument that is sent as a list of one element
- a single argument that is sent by itself
- a dictionary (only Query and QueryFields)

This inconsistency makes it not only harder to auto-generate the
HTools LUXI interface, but also in general to check the arguments and
(if we ever want to do it) auto-generate the Python LUXI client.

Compare this with the node daemon, which uses consistently a list for
its arguments, and even with way more changes over time had no issues
with extending the interface.

In case we want to extend a call, there are two options:

- preferred: add a new call, keep the old one unchanged
- possible: add further parameters to the current argument list

The patch against HTools will follow—sending separately as the Python
changes are very clear by themselves.
Signed-off-by: default avatarIustin Pop <>
Reviewed-by: default avatarMichael Hanselmann <>
parent 2e5c33db
......@@ -439,14 +439,17 @@ class Client(object):
"""Send a generic request and return the response.
if not isinstance(args, (list, tuple)):
raise errors.ProgrammerError("Invalid parameter passed to CallMethod:"
" expected list, got %s" % type(args))
return CallLuxiMethod(self._SendMethodCall, method, args,
def SetQueueDrainFlag(self, drain_flag):
return self.CallMethod(REQ_QUEUE_SET_DRAIN_FLAG, drain_flag)
return self.CallMethod(REQ_QUEUE_SET_DRAIN_FLAG, (drain_flag, ))
def SetWatcherPause(self, until):
return self.CallMethod(REQ_SET_WATCHER_PAUSE, [until])
return self.CallMethod(REQ_SET_WATCHER_PAUSE, (until, ))
def SubmitJob(self, ops):
ops_state = map(lambda op: op.__getstate__(), ops)
......@@ -459,10 +462,10 @@ class Client(object):
return self.CallMethod(REQ_SUBMIT_MANY_JOBS, jobs_state)
def CancelJob(self, job_id):
return self.CallMethod(REQ_CANCEL_JOB, job_id)
return self.CallMethod(REQ_CANCEL_JOB, (job_id, ))
def ArchiveJob(self, job_id):
return self.CallMethod(REQ_ARCHIVE_JOB, job_id)
return self.CallMethod(REQ_ARCHIVE_JOB, (job_id, ))
def AutoArchiveJobs(self, age):
timeout = (DEF_RWTO - 1) / 2
......@@ -510,8 +513,7 @@ class Client(object):
@rtype: L{objects.QueryResponse}
req = objects.QueryRequest(what=what, fields=fields, qfilter=qfilter)
result = self.CallMethod(REQ_QUERY, req.ToDict())
result = self.CallMethod(REQ_QUERY, (what, fields, qfilter))
return objects.QueryResponse.FromDict(result)
def QueryFields(self, what, fields):
......@@ -523,8 +525,7 @@ class Client(object):
@rtype: L{objects.QueryFieldsResponse}
req = objects.QueryFieldsRequest(what=what, fields=fields)
result = self.CallMethod(REQ_QUERY_FIELDS, req.ToDict())
result = self.CallMethod(REQ_QUERY_FIELDS, (what, fields))
return objects.QueryFieldsResponse.FromDict(result)
def QueryJobs(self, job_ids, fields):
......@@ -546,7 +547,7 @@ class Client(object):
return self.CallMethod(REQ_QUERY_CLUSTER_INFO, ())
def QueryConfigValues(self, fields):
return self.CallMethod(REQ_QUERY_CONFIG_VALUES, fields)
return self.CallMethod(REQ_QUERY_CONFIG_VALUES, (fields, ))
def QueryTags(self, kind, name):
return self.CallMethod(REQ_QUERY_TAGS, (kind, name))
......@@ -193,6 +193,9 @@ class ClientOps:
queue = self.server.context.jobqueue
# TODO: Parameter validation
if not isinstance(args, (tuple, list)):"Received invalid arguments of type '%s'", type(args))
raise ValueError("Invalid arguments type '%s'" % type(args))
# TODO: Rewrite to not exit in each 'if/elif' branch
......@@ -209,12 +212,12 @@ class ClientOps:
return queue.SubmitManyJobs(jobs)
elif method == luxi.REQ_CANCEL_JOB:
job_id = args
(job_id, ) = args"Received job cancel request for %s", job_id)
return queue.CancelJob(job_id)
elif method == luxi.REQ_ARCHIVE_JOB:
job_id = args
(job_id, ) = args"Received job archive request for %s", job_id)
return queue.ArchiveJob(job_id)
......@@ -231,7 +234,8 @@ class ClientOps:
prev_log_serial, timeout)
elif method == luxi.REQ_QUERY:
req = objects.QueryRequest.FromDict(args)
(what, fields, qfilter) = args
req = objects.QueryRequest(what=what, fields=fields, qfilter=qfilter)
if req.what in constants.QR_VIA_OP:
result = self._Query(opcodes.OpQuery(what=req.what, fields=req.fields,
......@@ -249,7 +253,8 @@ class ClientOps:
return result
elif method == luxi.REQ_QUERY_FIELDS:
req = objects.QueryFieldsRequest.FromDict(args)
(what, fields) = args
req = objects.QueryFieldsRequest(what=what, fields=fields)
fielddefs = query.ALL_FIELDS[req.what]
......@@ -298,7 +303,7 @@ class ClientOps:
return self._Query(op)
elif method == luxi.REQ_QUERY_EXPORTS:
nodes, use_locking = args
(nodes, use_locking) = args
if use_locking:
raise errors.OpPrereqError("Sync queries are not allowed",
......@@ -307,7 +312,7 @@ class ClientOps:
return self._Query(op)
elif method == luxi.REQ_QUERY_CONFIG_VALUES:
fields = args
(fields, ) = args"Received config values query request for %s", fields)
op = opcodes.OpClusterConfigQuery(output_fields=fields)
return self._Query(op)
......@@ -318,7 +323,7 @@ class ClientOps:
return self._Query(op)
elif method == luxi.REQ_QUERY_TAGS:
kind, name = args
(kind, name) = args"Received tags query request")
op = opcodes.OpTagsGet(kind=kind, name=name)
return self._Query(op)
......@@ -331,7 +336,7 @@ class ClientOps:
return self.server.context.glm.OldStyleQueryLocks(fields)
elif method == luxi.REQ_QUEUE_SET_DRAIN_FLAG:
drain_flag = args
(drain_flag, ) = args"Received queue drain flag change request to %s",
return queue.SetDrainFlag(drain_flag)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment