summaryrefslogtreecommitdiffstats
path: root/src/spdk/scripts/rpc/client.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/spdk/scripts/rpc/client.py')
-rw-r--r--src/spdk/scripts/rpc/client.py100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/spdk/scripts/rpc/client.py b/src/spdk/scripts/rpc/client.py
new file mode 100644
index 00000000..6a71ab51
--- /dev/null
+++ b/src/spdk/scripts/rpc/client.py
@@ -0,0 +1,100 @@
+import json
+import socket
+import time
+
+
+def print_dict(d):
+ print(json.dumps(d, indent=2))
+
+
+class JSONRPCException(Exception):
+ def __init__(self, message):
+ self.message = message
+
+
+class JSONRPCClient(object):
+ def __init__(self, addr, port=None, verbose=False, timeout=60.0):
+ self.verbose = verbose
+ self.timeout = timeout
+ try:
+ if addr.startswith('/'):
+ self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ self.sock.connect(addr)
+ elif ':' in addr:
+ for res in socket.getaddrinfo(addr, port, socket.AF_INET6, socket.SOCK_STREAM, socket.SOL_TCP):
+ af, socktype, proto, canonname, sa = res
+ self.sock = socket.socket(af, socktype, proto)
+ self.sock.connect(sa)
+ else:
+ self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.sock.connect((addr, port))
+ except socket.error as ex:
+ raise JSONRPCException("Error while connecting to %s\n"
+ "Error details: %s" % (addr, ex))
+
+ def __del__(self):
+ self.sock.close()
+
+ def call(self, method, params={}, verbose=False):
+ req = {}
+ req['jsonrpc'] = '2.0'
+ req['method'] = method
+ req['id'] = 1
+ if (params):
+ req['params'] = params
+ reqstr = json.dumps(req)
+
+ verbose = verbose or self.verbose
+
+ if verbose:
+ print("request:")
+ print(json.dumps(req, indent=2))
+
+ self.sock.sendall(reqstr.encode("utf-8"))
+ buf = ''
+ closed = False
+ response = {}
+ start_time = time.clock()
+
+ while not closed:
+ try:
+ timeout = self.timeout - (time.clock() - start_time)
+ if timeout <= 0.0:
+ break
+
+ self.sock.settimeout(timeout)
+ newdata = self.sock.recv(4096)
+ if (newdata == b''):
+ closed = True
+
+ buf += newdata.decode("utf-8")
+ response = json.loads(buf)
+ except socket.timeout:
+ break
+ except ValueError:
+ continue # incomplete response; keep buffering
+ break
+
+ if not response:
+ if method == "kill_instance":
+ return {}
+ if closed:
+ msg = "Connection closed with partial response:"
+ else:
+ msg = "Timeout while waiting for response:"
+ msg = "\n".join([msg, buf])
+ raise JSONRPCException(msg)
+
+ if verbose:
+ print("response:")
+ print(json.dumps(response, indent=2))
+
+ if 'error' in response:
+ msg = "\n".join(["Got JSON-RPC error response",
+ "request:",
+ json.dumps(req, indent=2),
+ "response:",
+ json.dumps(response['error'], indent=2)])
+ raise JSONRPCException(msg)
+
+ return response['result']