diff --git a/doc/client-api.txt b/doc/client-api.txt new file mode 100644 index 0000000000000000000000000000000000000000..8121d92218490a83b5f3c4856b0cc8e9d775599b --- /dev/null +++ b/doc/client-api.txt @@ -0,0 +1,155 @@ +Notes about the client api +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Starting with Ganeti 1.3, the individual commands (gnt-...) do not +execute code directly, but instead via a master daemon. The +communication between these commands and the daemon will be language +agnostic, and we will be providing a python library implementing all +operations. + +TODO: add tags support, add gnt-instance info implementation, document +all results from query and all opcode fields + +Protocol +======== + +The protocol for communication will consist of passing JSON-encoded +messages over a UNIX socket. The protocol will be send message, receive +message, send message, ..., etc. Each message (either request or +response) will end (after the JSON message) with a ``ETX`` character +(ascii decimal 3), which is not a valid character in JSON messages and +thus can serve as a message delimiter. Quoting from the +http://www.json.org grammar:: + + char: any unicode character except " or \ or control character + +There are three request types than can be done: + + - submit job; a job is a sequence of opcodes that modify the cluster + - abort a job; in some circumstances, a job can be aborted; the exact + conditions depend on the master daemon implementation and clients + should not rely on being able to abort jobs + - query objects; this is a generic form of query that works for all + object types + +All requests will be encoded as a JSON object, having three fields: + + - ``request``: string, one of ``submit``, ``abort``, ``query`` + - ``data``: the payload of the request, variable type based on request + - ``version``: the protocol version spoken by the client; we are + describing here the version 0 + +The response to any request will be a JSON object, with two fields: + + - ``success``: either ``true`` or ``false`` denoting whether the + request was successful or not + - ``result``: the result of the request (depends on request type) if + successful, otherwise the error message (describing the failure) + +The server has no defined upper-limit on the time it will take to +respond to a request, so the clients should implement their own timeout +handling. Note though that most requests should be answered quickly, if +the cluster is in a normal state. + +Submit +------ + +The submit ``data`` field will be a JSON object - a (partial) Job +description. It will have the following fields: + + - ``opcode_list``: a list of opcode objects, see below + +The opcode objects supported will mostly be the ones supported by the +internal Ganeti implementation; currently there is no well-defined +definition of them (work in progress). + +Each opcode will be represented in the message list as an object: + + - ``OP_ID``: an opcode id; this will be equivalent to the ``OP_ID`` + class attribute on opcodes (in lib/opcodes.py) + - other fields: as needed by the opcode in question + +Small example, request:: + + { + "opcode_list": [ + { + "instance_name": "instance1.example.com", + "OP_ID": "OP_INSTANCE_SHUTDOWN" + } + ] + } + +And response:: + + { + "result": "1104", + "success": true + } + +The result of the submit request will be if successful, a single JSON +value denoting the job ID. While the job ID might be (or look like) an +integer, the clients should not depend on this and treat this ID as an +opaque identifier. + +Abort +----- + +The abort request data will be a single job ID (as returned by submit or +query jobs). The result will hold no data (i.e. it will be a JSON +``null`` value), if successful, and will be the error message if it +fails. + +Query +----- + +The ``data`` argument to the query request is a JSON object containing: + + - ``object``: the object type to be queried + - ``names``: if querying a list of objects, this can restrict the + query to a subset of the entire list + - ``fields``: the list of informations that we are interested in + +The valid values for the ``object`` field is: + + - ``cluster`` + - ``node`` + - ``instance`` + +For the ``cluster`` object, the ``names`` parameter is unused and must +be null. + +The result value will be a list of lists: each row in the top-level list +will hold the result for a single object, and each row in the per-object +results will hold a result field, in the same order as the ``fields`` +value. + +Small example, request:: + + { + "data": { + "fields": [ + "name", + "admin_memory" + ], + "object": "instance" + }, + "request": "query" + } + +And response:: + + { + "result": [ + [ + "instance1.example.com", + "128" + ], + [ + "instance2.example.com", + "4096" + ] + ], + "success": true + } +