Change in vdsm[master]: Add usbutils req to usbhook
by Dan Kenigsberg
Dan Kenigsberg has uploaded a new change for review.
Change subject: Add usbutils req to usbhook
......................................................................
Add usbutils req to usbhook
Change-Id: I2644a294ebea1590cae571660e3ed3b61e564ef8
Signed-off-by: Dan Kenigsberg <danken(a)redhat.com>
---
M vdsm.spec.in
1 file changed, 1 insertion(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/93/10893/1
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 83ff539..ed91783 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -283,6 +283,7 @@
%package hook-hostusb
Summary: Allow attaching USB device from host
BuildArch: noarch
+Requires: usbutils
%description hook-hostusb
Hook is getting vendor and product id of USB device
--
To view, visit http://gerrit.ovirt.org/10893
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I2644a294ebea1590cae571660e3ed3b61e564ef8
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Dan Kenigsberg <danken(a)redhat.com>
11 years, 5 months
Change in vdsm[master]: Refactor communication infra
by smizrahi@redhat.com
Saggi Mizrahi has uploaded a new change for review.
Change subject: Refactor communication infra
......................................................................
Refactor communication infra
This is one phase in many, there is still a lot to do but it's a good
step in the right direction.
As I said, this is far from complete but it's enough code for a commit
IMO.
- Properly layer code to allow multiple transports
- Isolate json-rpc logic to the actual json-rpc layer
- Someone more conferment but still incomplete json-rpc 2.0 implementation
- Make sure tcp handling uses one thread
- Write some more tests
Change-Id: I7a65364824cc8433263ccf6ed44f1f97141eff2c
Signed-off-by: Saggi Mizrahi <smizrahi(a)redhat.com>
---
M tests/Makefile.am
M tests/apiTests.py
A tests/jsonRpcTests.py
M vdsm/clientIF.py
M vdsm/utils.py
M vdsm_api/BindingJsonRpc.py
M vdsm_api/Bridge.py
A vdsm_api/jsonrpc/__init__.py
A vdsm_api/jsonrpc/tcpReactor.py
9 files changed, 617 insertions(+), 99 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/86/9986/1
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8ad34e2..c26adc3 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -32,6 +32,7 @@
gluster_cli_tests.py \
guestIFTests.py \
hooksTests.py \
+ jsonRpcTests.py \
libvirtvmTests.py \
lsblkTests.py \
main.py \
diff --git a/tests/apiTests.py b/tests/apiTests.py
index bf40f9e..d770cf8 100644
--- a/tests/apiTests.py
+++ b/tests/apiTests.py
@@ -30,7 +30,9 @@
from testrunner import VdsmTestCase as TestCaseBase
from vdsm import constants
import BindingJsonRpc
+import jsonrpc
import apiData
+
ip = '0.0.0.0'
port = 9824
@@ -144,7 +146,9 @@
# Support parallel testing. Try hard to find an open port to use
while True:
try:
- server = BindingJsonRpc.BindingJsonRpc(bridge, ip, port)
+ server = BindingJsonRpc.BindingJsonRpc(bridge,
+ [('tcp', {"ip": ip,
+ "port": port})])
break
except socket.error as ex:
if ex.errno == errno.EADDRINUSE:
@@ -195,16 +199,21 @@
resp = msize + msg
return resp
+ def _createRequest(self, method, reqId=None, params=()):
+ return {'jsonrpc': '2.0', "id": reqId, "method": method,
+ "params": params}
+
def sendMessage(self, msg):
with closing(socket.socket(socket.AF_INET,
socket.SOCK_STREAM)) as sock:
+ sock.settimeout(3)
try:
sock.connect((ip, port))
except socket.error, e:
raise ConnectionError("Unable to connect to server: %s", e)
try:
sock.sendall(msg)
- except socket.error, e:
+ except (socket.error, socket.timeout), e:
raise ProtocolError("Unable to send request: %s", e)
try:
data = sock.recv(JsonRawTest._Size.size)
@@ -224,7 +233,9 @@
def testPing(self):
self.clearAPI()
self.programAPI("testPing")
- msg = self.buildMessage({'id': 1, 'method': 'Host.ping',
+ msg = self.buildMessage({'jsonrpc': '2.0',
+ 'id': 1,
+ 'method': 'Host.ping',
'params': {}})
reply = self.sendMessage(msg)
self.assertFalse('error' in reply)
@@ -233,21 +244,26 @@
def testPingError(self):
self.clearAPI()
self.programAPI("testPingError")
- msg = self.buildMessage({'id': 1, 'method': 'Host.ping',
+ msg = self.buildMessage({'jsonrpc': '2.0',
+ 'id': 1, 'method': 'Host.ping',
'params': {}})
reply = self.sendMessage(msg)
self.assertEquals(1, reply['error']['code'])
self.assertFalse('result' in reply)
def testNoMethod(self):
- msg = self.buildMessage({'id': 1, 'method': 'Host.fake'})
+ msg = self.buildMessage({'jsonrpc': '2.0',
+ 'id': 1,
+ 'method': 'Host.fake'})
reply = self.sendMessage(msg)
- self.assertEquals(4, reply['error']['code'])
+ self.assertEquals(jsonrpc.JsonRpcMethodNotFoundError().code,
+ reply['error']['code'])
def testBadMethod(self):
- msg = self.buildMessage({'id': 1, 'method': 'malformed\''})
+ msg = self.buildMessage(self._createRequest('malformed\'', 1))
reply = self.sendMessage(msg)
- self.assertEquals(4, reply['error']['code'])
+ self.assertEquals(jsonrpc.JsonRpcMethodNotFoundError().code,
+ reply['error']['code'])
def testMissingSize(self):
self.assertRaises(ProtocolError, self.sendMessage,
@@ -257,7 +273,9 @@
msg = "malformed message"
msize = JsonRawTest._Size.pack(len(msg))
msg = msize + msg
- self.assertRaises(ProtocolError, self.sendMessage, msg)
+ reply = self.sendMessage(msg)
+ self.assertEquals(jsonrpc.JsonRpcParseError().code,
+ reply['error']['code'])
def testSynchronization(self):
def doPing(msg):
@@ -266,7 +284,9 @@
ret = self.sendMessage(msg)
self.assertFalse('error' in ret)
- msg = self.buildMessage({'id': 1, 'method': 'Host.ping'})
+ msg = self.buildMessage({'jsonrpc': '2.0',
+ 'id': 1,
+ 'method': 'Host.ping'})
# Send Truncated message
self.assertRaises(ProtocolError, doPing, msg[:-1])
@@ -280,6 +300,8 @@
doPing(msg)
def testInternalError(self):
- msg = self.buildMessage({'id': 1, 'method': 'Host.ping'})
+ msg = self.buildMessage({'jsonrpc': '2.0',
+ 'id': 1, 'method': 'Host.ping'})
reply = self.sendMessage(msg)
- self.assertEquals(5, reply['error']['code'])
+ self.assertEquals(jsonrpc.JsonRpcInternalError().code,
+ reply['error']['code'])
diff --git a/tests/jsonRpcTests.py b/tests/jsonRpcTests.py
new file mode 100644
index 0000000..85b98a6
--- /dev/null
+++ b/tests/jsonRpcTests.py
@@ -0,0 +1,158 @@
+#
+# Copyright 2012 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+import threading
+import socket
+from contextlib import contextmanager
+from functools import partial
+from contextlib import closing
+
+from testrunner import VdsmTestCase as TestCaseBase, \
+ expandPermutations, \
+ permutations
+
+from jsonrpc import tcpReactor
+
+PORT_RANGE = xrange(49152, 65535)
+
+
+_distributedPorts = []
+
+
+def _getFreePort():
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ with closing(sock):
+ for port in PORT_RANGE:
+ if port in _distributedPorts:
+ continue
+
+ try:
+ sock.bind(("0.0.0.0", port))
+ except:
+ continue
+
+ _distributedPorts.append(port)
+ return port
+ else:
+ raise Exception("Could not find a free port")
+
+
+@contextmanager
+def _tcpServerConstructor(messageHandler):
+ port = _getFreePort()
+ address = ("localhost", port)
+ reactor = tcpReactor.TCPReactor(address, messageHandler)
+
+ try:
+ yield reactor, partial(TCPRactorClient, address)
+ finally:
+ reactor.stop()
+
+
+REACTOR_CONSTRUCTORS = {"tcp": _tcpServerConstructor}
+REACTOR_TYPE_PERMUTATIONS = [[r] for r in REACTOR_CONSTRUCTORS.iterkeys()]
+
+
+@contextmanager
+def constructReactor(tp, messageHandler):
+ with REACTOR_CONSTRUCTORS[tp](messageHandler) as res:
+ yield res
+
+
+class _EchoMessageHandler(object):
+ def handleMessage(self, msgCtx):
+ msgCtx.sendReply(msgCtx.data)
+
+
+class TCPRactorClient(object):
+ def __init__(self, address):
+ self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.address = address
+
+ def connect(self):
+ self.sock.connect(self.address)
+
+ def sendMessage(self, msg, timeout=None):
+ msg = tcpReactor._Size.pack(len(msg)) + msg
+ self.sock.settimeout(timeout)
+ self.sock.send(msg)
+
+ def recvMessage(self, timeout=None):
+ self.sock.settimeout(timeout)
+ rawSize = self.sock.recv(tcpReactor._Size.size)
+ size = tcpReactor._Size.unpack(rawSize)[0]
+ return self.sock.recv(size)
+
+ def close(self):
+ self.sock.close()
+
+
+@expandPermutations
+class ReactorTests(TestCaseBase):
+ @permutations(REACTOR_TYPE_PERMUTATIONS)
+ def test(self, reactorType):
+ data = """I've seen things you people wouldn't believe. Attack ships on
+ fire off the shoulder of Orion. I've watched c-beams glitter
+ in the dark near the Tannhauser Gate. All those ... moments
+ will be lost in time, like tears...in rain. Time to die."""
+ # (C) Blade Runner
+
+ msgHandler = _EchoMessageHandler()
+
+ def serve(reactor):
+ try:
+ reactor.serve_forever()
+ except socket.error as e:
+ pass
+ except Exception as e:
+ self.log.error("Server died unexpectedly", exc_info=True)
+ self.fail("Server died: (%s) %s" % (type(e), e))
+
+ with constructReactor(reactorType, msgHandler) as (reactor,
+ clientFactory):
+ t = threading.Thread(target=serve, args=(reactor,))
+ t.setDaemon(True)
+ t.start()
+
+ clientNum = 1
+ repeats = 1
+ subRepeats = 1
+
+ clients = []
+ try:
+ for i in range(clientNum):
+ client = clientFactory()
+ client.connect()
+ clients.append(client)
+
+ for i in range(repeats):
+ for client in clients:
+ for i in range(subRepeats):
+ self.log.info("Sending message...")
+ client.sendMessage(data, 1)
+
+ for i in range(repeats * subRepeats):
+ for client in clients:
+ self.log.info("Waiting for reply...")
+ retData = client.recvMessage(1)
+ self.log.info("Asserting reply...")
+ self.assertEquals(retData, data)
+ finally:
+ for client in clients:
+ client.close()
diff --git a/vdsm/clientIF.py b/vdsm/clientIF.py
index 65b4e72..48a9cf8 100644
--- a/vdsm/clientIF.py
+++ b/vdsm/clientIF.py
@@ -156,8 +156,8 @@
schema = os.path.join(constants.P_VDSM, 'vdsmapi-schema.json')
ip = self._getServerIP(config.get('addresses', 'management_ip'))
port = config.getint('addresses', 'json_port')
- self.bindings['json'] = BindingJsonRpc(DynamicBridge(schema),
- ip, port)
+ conf = [('tcp', {"ip": ip, "port": port})]
+ self.bindings['json'] = BindingJsonRpc(DynamicBridge(schema), conf)
def _prepareBindings(self):
self.bindings = {}
diff --git a/vdsm/utils.py b/vdsm/utils.py
index b4614e7..bb012d0 100644
--- a/vdsm/utils.py
+++ b/vdsm/utils.py
@@ -905,6 +905,38 @@
return unicode(self.cmd)
+class PollEvent(object):
+ def __init__(self):
+ self._r, self._w = os.pipe()
+ self._lock = threading.Lock()
+ self._isSet = False
+
+ def fileno(self):
+ return self._r
+
+ def set(self):
+ with self._lock:
+ if self._isSet:
+ return
+
+ os.write(self._w, "a")
+ self._isSet = True
+
+ def isSet(self):
+ return self._isSet
+
+ def clear(self):
+ with self._lock:
+ if not self._isSet:
+ return
+
+ os.read(self._r, 1)
+
+ def __del__(self):
+ os.close(self._r)
+ os.close(self._w)
+
+
def retry(func, expectedException=Exception, tries=None,
timeout=None, sleep=1):
"""
diff --git a/vdsm_api/BindingJsonRpc.py b/vdsm_api/BindingJsonRpc.py
index 1ddc863..b8c8658 100644
--- a/vdsm_api/BindingJsonRpc.py
+++ b/vdsm_api/BindingJsonRpc.py
@@ -14,86 +14,42 @@
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import threading
-import SocketServer
-import json
import logging
-
import struct
-
_Size = struct.Struct("!Q")
+from jsonrpc import JsonRpcServer
+from jsonrpc.tcpReactor import TCPReactor
-class BindingJsonRpc:
+
+class BindingJsonRpc(object):
log = logging.getLogger('BindingJsonRpc')
- def __init__(self, bridge, ip, port):
+ def __init__(self, bridge, backendConfig):
+ reactors = []
self.bridge = bridge
- self.serverPort = port
- self.serverIP = ip
- self._createServer()
+ self.server = JsonRpcServer(bridge)
+ for backendType, cfg in backendConfig:
+ if backendType == "tcp":
+ reactors.append(self._createTcpReactor(cfg))
- def _createServer(self):
- ip = self.serverIP or '0.0.0.0'
- self.server = JsonRpcServer((ip, self.serverPort), JsonRpcTCPHandler,
- self.bridge)
+ self._reactors = reactors
+
+ def _createTcpReactor(self, cfg):
+ address = cfg.get("ip", "0.0.0.0")
+ port = cfg.get("port", 4044)
+ return TCPReactor((address, port), self.server)
def start(self):
- t = threading.Thread(target=self.server.serve_forever,
- name='JsonRpc')
- t.setDaemon(True)
- t.start()
+ for reactor in self._reactors:
+ reactorName = reactor.__class__.__name__
+ t = threading.Thread(target=reactor.serve_forever,
+ name='JsonRpc (%s)' % reactorName)
+ t.setDaemon(True)
+ t.start()
def prepareForShutdown(self):
self.server.shutdown()
-
-
-class JsonRpcServer(SocketServer.TCPServer):
- def __init__(self, addrInfo, handler, bridge):
- self.bridge = bridge
- self.allow_reuse_address = True
- SocketServer.TCPServer.__init__(self, addrInfo, handler)
-
-
-class JsonRpcTCPHandler(SocketServer.StreamRequestHandler):
- log = logging.getLogger('JsonRpcTCPHandler')
-
- def handle(self):
- while True:
- # self.request is the TCP socket connected to the client
- try:
- data = self.request.recv(_Size.size)
- if len(data) != _Size.size:
- self.log.debug("Connection closed")
- return
- msgLen = _Size.unpack(data)[0]
- msg = json.loads(self.request.recv(msgLen))
- except:
- self.log.warn("Unexpected exception", exc_info=True)
- return
- self.log.debug('Received request: %s', msg)
-
- try:
- ret = self.server.bridge.dispatch(msg['method'],
- msg.get('params', {}))
- resp = self.buildResponse(msg['id'], ret)
- except Exception, e:
- self.log.warn("Dispatch error", exc_info=True)
- err = {'error': {'code': 5,
- 'message': 'Dispatch error: %s' % e}}
- resp = self.buildResponse(msg['id'], err)
-
- self.wfile.write(resp)
- self.wfile.flush()
-
- def buildResponse(self, msgId, result):
- msgData = {'id': msgId}
- if result['error']['code'] != 0:
- msgData['error'] = result['error']
- else:
- msgData['result'] = result['result']
- msg = json.dumps(msgData)
- msg = msg.encode('utf-8')
- self.log.debug('Sending reply: %s', msg)
- msize = _Size.pack(len(msg))
- return msize + msg
+ for reactor in self._reactors:
+ reactor.stop()
diff --git a/vdsm_api/Bridge.py b/vdsm_api/Bridge.py
index d93dc22..08970ba 100644
--- a/vdsm_api/Bridge.py
+++ b/vdsm_api/Bridge.py
@@ -14,10 +14,12 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
from functools import partial
+
import vdsmapi
import logging
import types
import API
+import jsonrpc
class VdsmError(Exception):
@@ -26,22 +28,26 @@
self.message = message
-class MethodBridge(object):
+class DynamicBridge(object):
+ def __init__(self, schema):
+ self._parseSchema(schema)
+
def dispatch(self, name, argobj):
methodName = name.replace('.', '_')
result = None
- error = {'code': 0, 'message': 'Success'}
try:
fn = getattr(self, methodName)
except AttributeError:
- error = {'code': 4,
- 'message': "Operation '%s' not supported" % name}
- return {'result': result, 'error': error}
+ raise jsonrpc.JsonRpcMethodNotFoundError()
+
try:
result = fn(argobj)
except VdsmError, e:
- error = {'code': e.code, 'message': e.message}
- return {'result': result, 'error': error}
+ # TBD: Do we really want to always log here
+ self.log.debug("Operation failed, returning error", exc_info=True)
+ raise jsonrpc.JsonRpcError(e.code, e.message)
+
+ return result
def _getArgs(self, argobj, arglist):
return tuple(argobj[arg] for arg in arglist if arg in argobj)
@@ -53,11 +59,6 @@
return response[member]
except KeyError:
raise VdsmError(5, "Response is missing '%s' member" % member)
-
-
-class DynamicBridge(MethodBridge):
- def __init__(self, schema):
- self._parseSchema(schema)
def _parseSchema(self, schema):
self.commands = {}
@@ -82,7 +83,7 @@
className, methodName = attr.split('_')
return partial(self._dynamicMethod, className, methodName)
else:
- raise AttributeError()
+ raise AttributeError(attr)
def _getArgList(self, cmd):
return self.commands[cmd].get('data', {}).keys()
@@ -148,15 +149,30 @@
self._typeFixup('return', retType, result)
return result
- def _dynamicMethod(self, className, methodName, argobj):
+ def _nameArgs(self, args, kwargs, arglist):
+ kwargs = kwargs.copy()
+ for i, arg in enumerate(args):
+ argName = arglist[i]
+ kwargs[argName] = arg
+
+ return kwargs
+
+ def _dynamicMethod(self, className, methodName, *args, **kwargs):
cmd = '%s_%s' % (className, methodName)
- ctorArgObj = argobj.get('__obj__', {})
+
+ # __obj__ is deprecated, support here is only for BC until the patches
+ # that remove it get pushed in.
+ ctorArgObj = kwargs.pop('__obj__', {})
ctorargs = self._getArgs(ctorArgObj, self._getObjargList(className))
+ # This might look a bit wasteful because we unpack the argobj in the
+ # next line. I put this just so I need to do minimal changes to the
+ # rest of the code but still support an arglist
+ argobj = self._nameArgs(args, kwargs, self._getArgList(cmd))
args = self._getArgs(argobj, self._getArgList(cmd))
apiobj = self._getApiClass(className)
api = apiobj(*ctorargs)
- self._fixupArgs(cmd, args)
+ self._fixupArgs(cmd, argobj)
# Call the override function (if given). Otherwise, just call directly
fn = command_info.get(cmd, {}).get('call')
@@ -169,7 +185,7 @@
if result['status']['code']:
code = result['status']['code']
msg = result['status']['message']
- raise VdsmError(code, msg)
+ raise jsonrpc.JsonRpcError(code, msg)
retfield = command_info.get(cmd, {}).get('ret')
if isinstance(retfield, types.FunctionType):
diff --git a/vdsm_api/jsonrpc/__init__.py b/vdsm_api/jsonrpc/__init__.py
new file mode 100644
index 0000000..43e4199
--- /dev/null
+++ b/vdsm_api/jsonrpc/__init__.py
@@ -0,0 +1,176 @@
+# Copyright (C) 2012 Saggi Mizrahi, Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+import json
+import logging
+
+__all__ = ["tcpReactor"]
+
+
+class JsonRpcError(RuntimeError):
+ def __init__(self, code, msg):
+ self.code = code
+ self._msg = msg
+
+
+class JsonRpcParseError(JsonRpcError):
+ def __init__(self):
+ JsonRpcError.__init__(self, -32700,
+ "Invalid JSON was received by the server. "
+ "An error occurred on the server while parsing "
+ "the JSON text.")
+
+
+class JsonRpcInvalidRequestError(JsonRpcError):
+ def __init__(self):
+ JsonRpcError.__init__(self, -32600,
+ "The JSON sent is not a valid Request object.")
+
+
+class JsonRpcMethodNotFoundError(JsonRpcError):
+ def __init__(self):
+ JsonRpcError.__init__(self, -32601,
+ "The method does not exist / is not available.")
+
+
+class JsonRpcInvalidParamsError(JsonRpcError):
+ def __init__(self):
+ JsonRpcError.__init__(self, -32602,
+ "Invalid method parameter(s).")
+
+
+class JsonRpcInternalError(JsonRpcError):
+ def __init__(self):
+ JsonRpcError.__init__(self, -32603,
+ "Internal JSON-RPC error.")
+
+
+class JsonRpcRequest(object):
+ def __init__(self, method, params, reqId):
+ self.method = method
+ self.params = params
+ self.id = reqId
+
+ def invokeFunction(self, func):
+ if isinstance(self.params, list):
+ return func(*self.params)
+ else:
+ return func(**self.params)
+
+ def isNotification(self):
+ return self.id is None
+
+
+class JsonRpcServer(object):
+ log = logging.getLogger("JsonRpcServer")
+
+ def __init__(self, bridge):
+ self._bridge = bridge
+
+ def _parseMessage(self, msg):
+ try:
+ return json.loads(msg, 'utf-8')
+ except:
+ raise JsonRpcParseError()
+
+ def _parseRequest(self, obj):
+ if obj.get("jsonrpc") != "2.0":
+ raise JsonRpcInvalidRequestError()
+
+ method = obj.get("method")
+ if method is None:
+ raise JsonRpcInvalidRequestError()
+
+ reqId = obj.get("id")
+ if not isinstance(reqId, int):
+ raise JsonRpcInvalidRequestError()
+
+ params = obj.get('params', [])
+ if not isinstance(params, (list, dict)):
+ raise JsonRpcInvalidRequestError()
+
+ return JsonRpcRequest(method, params, reqId)
+
+ def _jsonError2Response(self, err, req):
+ respId = None
+ if req is not None:
+ respId = req.id
+
+ return json.dumps({"jsonrpc": "2.0",
+ "error": {"code": err.code, "message": err.message},
+ "id": respId})
+
+ def _generateResponse(self, req, result):
+ return json.dumps({"jsonrpc": "2.0",
+ "result": result,
+ "id": req.id}, 'utf-8')
+
+ def _processRequest(self, srv, conn, req, method):
+ # TODO: Multithreading
+ resp = None
+ try:
+ res = req.invokeFunction(method)
+ resp = self._generateResponse(req, res)
+
+ except JsonRpcError as e:
+ if not req.isNotification():
+ resp = self._jsonError2Response(e, req)
+
+ self.log.error("Error in request", exc_info=True)
+ except:
+ if not req.isNotification():
+ resp = self._jsonError2Response(JsonRpcInternalError(), req)
+
+ self.log.error("Unexpected error in request", exc_info=True)
+
+ if req.isNotification():
+ return
+
+ srv.sendMessage(conn, self._jsonError2Response(e, resp))
+
+ def handleMessage(self, msgCtx):
+ #TODO: support batch requests
+ req = None
+ resp = None
+ try:
+ obj = self._parseMessage(msgCtx.data)
+ req = self._parseRequest(obj)
+
+ mangledMethod = req.method.replace(".", "_")
+ self.log.debug("Looking for method '%s' in bridge",
+ mangledMethod)
+ try:
+ method = getattr(self._bridge, mangledMethod)
+ except AttributeError:
+ raise JsonRpcMethodNotFoundError()
+ else:
+ res = req.invokeFunction(method)
+ resp = self._generateResponse(req, res)
+
+ except JsonRpcError as e:
+ resp = self._jsonError2Response(e, req)
+ self.log.error("Error processing request", exc_info=True)
+ except:
+ resp = self._jsonError2Response(JsonRpcInternalError(), req)
+ self.log.error("Unexpected error while processing request",
+ exc_info=True)
+
+ if resp is None:
+ return
+
+ # Notification don't respond even on errors
+ if req is not None and req.isNotification():
+ return
+
+ msgCtx.sendReply(resp)
diff --git a/vdsm_api/jsonrpc/tcpReactor.py b/vdsm_api/jsonrpc/tcpReactor.py
new file mode 100644
index 0000000..a815033
--- /dev/null
+++ b/vdsm_api/jsonrpc/tcpReactor.py
@@ -0,0 +1,157 @@
+# Copyright (C) 2012 Saggi Mizrahi, Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+import errno
+import struct
+import logging
+import socket
+from select import poll, POLLIN, POLLPRI, POLLERR, POLLHUP, POLLOUT
+
+from vdsm import utils
+
+_Size = struct.Struct("!Q")
+
+
+class TCPConnection(object):
+ def __init__(self, conn, buffsize=(2 ** 20)):
+ self._conn = conn
+ conn.setblocking(False)
+ self.buffsize = buffsize
+ self._buffer = ""
+ self._sendData = []
+
+ def fileno(self):
+ return self._conn.fileno()
+
+ def addSendData(self, data):
+ self._sendData.append(data)
+
+ def hasSendData(self):
+ return len(self._sendData) > 0
+
+ def processOutput(self):
+ try:
+ if (len(self._sendData) > 0):
+ data = self._sendData[0]
+ bsent = self._conn.send(data)
+ if bsent < len(data):
+ self._sendData[0] = data[:bsent]
+ else:
+ self._sendData.pop(0)
+ except (OSError, IOError) as e:
+ if e.errno not in (errno.EINTR, errno.EAGAIN):
+ raise
+
+ def processInput(self):
+ try:
+ self._buffer += self._conn.recv(self.buffsize - len(self._buffer))
+ except (OSError, IOError) as e:
+ if e.errno not in (errno.EINTR, errno.EAGAIN):
+ raise
+
+ buffLen = len(self._buffer)
+ if buffLen < _Size.size:
+ return
+
+ if buffLen > self.buffsize:
+ self._conn.close()
+ self.sendData = []
+
+ msgLen = _Size.unpack(self._buffer[:_Size.size])[0]
+ if (buffLen - _Size.size) < msgLen:
+ return None
+
+ msgStart = _Size.size
+ msgEnd = msgLen + _Size.size
+ res = self._buffer[msgStart:msgEnd]
+ self._buffer = self._buffer[msgEnd:]
+ return res
+
+
+class TCPMessageContext(object):
+
+ def __init__(self, server, conn, data):
+ self._server = server
+ self._conn = conn
+ self._data = data
+
+ @property
+ def data(self):
+ return self._data
+
+ def sendReply(self, data):
+ self._server.sendReply(self, data)
+
+
+class TCPReactor(object):
+ log = logging.getLogger("jsonrpc.TCPReactor")
+
+ def __init__(self, address, messageHandler):
+ self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self._addr = address
+ self._messageHandler = messageHandler
+ self._inputEvent = utils.PollEvent()
+ # TODO: Close on exec
+ self._sock.bind(self._addr)
+
+ def serve_forever(self):
+ sock = self._sock
+ sock.listen(1)
+ poller = poll()
+ poller.register(sock, POLLIN | POLLPRI)
+ poller.register(self._inputEvent, POLLIN | POLLPRI)
+ connections = {}
+ self.log.debug("Starting to accept clients")
+ while True:
+ for fd, conn in connections.iteritems():
+ if conn.hasSendData():
+ poller.modify(fd, (POLLIN | POLLPRI | POLLOUT))
+ else:
+ poller.modify(fd, (POLLIN | POLLPRI))
+
+ for fd, ev in poller.poll():
+ if ev & (POLLERR | POLLHUP):
+ if fd == sock.fileno():
+ self.log.info("Listening socket closed, shutting down")
+ return
+
+ self.log.debug("Connection closed")
+ poller.unregister(fd)
+ del connections[fd]
+
+ elif fd == self._inputEvent.fileno():
+ self._inputEvent.clear()
+
+ elif fd == sock.fileno():
+ conn, addr = sock.accept()
+ self.log.debug("Processing new connection")
+ connections[conn.fileno()] = TCPConnection(conn)
+ poller.register(conn, (POLLIN | POLLPRI))
+ else:
+ conn = connections[fd]
+ if ev & (POLLIN | POLLPRI):
+ msg = conn.processInput()
+ if msg is not None:
+ ctx = TCPMessageContext(self, conn, msg)
+ self._messageHandler.handleMessage(ctx)
+ if ev & POLLOUT:
+ conn.processOutput()
+
+ def sendReply(self, ctx, message):
+ conn = ctx._conn
+ conn.addSendData(_Size.pack(len(message)) + message)
+ self._inputEvent.set()
+
+ def stop(self):
+ self._sock.close()
--
To view, visit http://gerrit.ovirt.org/9986
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7a65364824cc8433263ccf6ed44f1f97141eff2c
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Saggi Mizrahi <smizrahi(a)redhat.com>
11 years, 5 months
Change in vdsm[master]: Moving pidStat function to utils
by ybronhei@redhat.com
Yaniv Bronhaim has uploaded a new change for review.
Change subject: Moving pidStat function to utils
......................................................................
Moving pidStat function to utils
As in general it doesn't serve only the storage part
Change-Id: Iad76fd978283c9dc55635075ff195211cced2d64
Signed-off-by: Yaniv Bronhaim <ybronhei(a)redhat.com>
---
M tests/miscTests.py
M tests/utilsTests.py
M vdsm/storage/blockSD.py
M vdsm/storage/misc.py
4 files changed, 21 insertions(+), 32 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/32/10932/1
diff --git a/tests/miscTests.py b/tests/miscTests.py
index cfa2f90..a949a09 100644
--- a/tests/miscTests.py
+++ b/tests/miscTests.py
@@ -101,20 +101,6 @@
sproc.wait()
-class PidStatTests(TestCaseBase):
- def test(self):
- args = [EXT_SLEEP, "3"]
- sproc = misc.execCmd(args, sync=False, sudo=False)
- stats = misc.pidStat(sproc.pid)
- pid = int(stats[0])
- # procName comes in the format of (procname)
- name = stats[1]
- self.assertEquals(pid, sproc.pid)
- self.assertEquals(name, args[0])
- sproc.kill()
- sproc.wait()
-
-
class EventTests(TestCaseBase):
def testEmit(self):
ev = threading.Event()
@@ -1039,7 +1025,7 @@
proc = misc.execCmd(cmd, sudo=False, nice=10, sync=False)
def test():
- nice = misc.pidStat(proc.pid)[18]
+ nice = utils.pidStat(proc.pid)[18]
self.assertEquals(nice, 10)
utils.retry(AssertionError, test, tries=10, sleep=0.1)
diff --git a/tests/utilsTests.py b/tests/utilsTests.py
index 745754d..cb32c65 100644
--- a/tests/utilsTests.py
+++ b/tests/utilsTests.py
@@ -19,6 +19,7 @@
#
from testrunner import VdsmTestCase as TestCaseBase
from vdsm import utils
+from storage import misc
class RetryTests(TestCaseBase):
@@ -43,3 +44,17 @@
sleep=0, stopCallback=stopCallback)
# Make sure we had the proper amount of iterations before failing
self.assertEquals(counter[0], limit)
+
+
+class PidStatTests(TestCaseBase):
+ def test(self):
+ args = ["sleep", "3"]
+ sproc = misc.execCmd(args, sync=False, sudo=False)
+ stats = utils.pidStat(sproc.pid)
+ pid = int(stats[0])
+ # procName comes in the format of (procname)
+ name = stats[1]
+ self.assertEquals(pid, sproc.pid)
+ self.assertEquals(name, args[0])
+ sproc.kill()
+ sproc.wait()
diff --git a/vdsm/storage/blockSD.py b/vdsm/storage/blockSD.py
index a63f2b3..8f596fe 100644
--- a/vdsm/storage/blockSD.py
+++ b/vdsm/storage/blockSD.py
@@ -33,6 +33,7 @@
from vdsm.config import config
from vdsm import constants
+from vdsm import utils
import misc
import fileUtils
import sd
@@ -1087,7 +1088,7 @@
for umountPid in umountPids:
try:
- state = misc.pidStat(umountPid)[2]
+ state = utils.pidStat(umountPid)[2]
mountPoint = misc.getCmdArgs(umountPid)[-1]
except:
# Process probably exited
diff --git a/vdsm/storage/misc.py b/vdsm/storage/misc.py
index 81cb9e7..5ec13e4 100644
--- a/vdsm/storage/misc.py
+++ b/vdsm/storage/misc.py
@@ -56,6 +56,7 @@
import inspect
from vdsm import constants
+from vdsm import utils
import storage_exception as se
from vdsm.betterPopen import BetterPopen
import fileUtils
@@ -1117,7 +1118,7 @@
continue
try:
- procName = pidStat(pid)[1]
+ procName = utils.pidStat(pid)[1]
if procName == name:
res.append(pid)
except (OSError, IOError):
@@ -1136,26 +1137,12 @@
# Retrying seems to solve it.
while len(res) == 0:
# cmdline is empty for zombie processes
- if pidStat(pid)[2] in ("Z", "z"):
+ if utils.pidStat(pid)[2] in ("Z", "z"):
return tuple()
res = _parseCmdLine(pid)
return res
-
-
-def pidStat(pid):
- res = []
- with open("/proc/%d/stat" % pid, "r") as f:
- statline = f.readline()
- procNameStart = statline.find("(")
- procNameEnd = statline.rfind(")")
- res.append(int(statline[:procNameStart]))
- res.append(statline[procNameStart + 1:procNameEnd])
- args = statline[procNameEnd + 2:].split()
- res.append(args[0])
- res.extend([int(item) for item in args[1:]])
- return tuple(res)
def tmap(func, iterable):
--
To view, visit http://gerrit.ovirt.org/10932
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iad76fd978283c9dc55635075ff195211cced2d64
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Yaniv Bronhaim <ybronhei(a)redhat.com>
11 years, 5 months
Change in vdsm[master]: Fix code style for API.
by asegurap@redhat.com
Antoni Segura Puimedon has uploaded a new change for review.
Change subject: Fix code style for API.
......................................................................
Fix code style for API.
Apply the code style suggestions in:
http://gerrit.ovirt.org/#/c/9993/1/vdsm/API.py
Change-Id: I5afe33338146506564d83983eb136c058fd25257
Signed-off-by: Antoni S. Puimedon <asegurap(a)redhat.com>
---
M vdsm/API.py
1 file changed, 4 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/50/10950/1
diff --git a/vdsm/API.py b/vdsm/API.py
index 4462033..16bebb5 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -166,8 +166,8 @@
pickledMachineParams = pickle.load(f)
if type(pickledMachineParams) == dict:
- self.log.debug('loaded pickledMachineParams '
- + str(pickledMachineParams))
+ self.log.debug('loaded pickledMachineParams ' +
+ str(pickledMachineParams))
self.log.debug('former conf ' + str(vmParams))
vmParams.update(pickledMachineParams)
finally:
@@ -231,8 +231,8 @@
if vmParams.get('display') not in ('vnc', 'qxl', 'qxlnc'):
return {'status': {'code': errCode['createErr']
['status']['code'],
- 'message': 'Unknown display type %s'
- % vmParams.get('display')}}
+ 'message': 'Unknown display type %s' %
+ vmParams.get('display')}}
if 'nicModel' not in vmParams:
vmParams['nicModel'] = config.get('vars', 'nic_model')
vmParams['displayIp'] = self._getNetworkIp(vmParams.get(
--
To view, visit http://gerrit.ovirt.org/10950
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I5afe33338146506564d83983eb136c058fd25257
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Antoni Segura Puimedon <asegurap(a)redhat.com>
11 years, 5 months
Change in vdsm[master]: tests: Fix parted_utils_tests break on fedora 18
by wudxw@linux.vnet.ibm.com
Mark Wu has uploaded a new change for review.
Change subject: tests: Fix parted_utils_tests break on fedora 18
......................................................................
tests: Fix parted_utils_tests break on fedora 18
parted 3.1 improves its support for loopback devices. The 'model' string
returned by libparted is updated to 'Loopback device'. For more information,
please see the parted commit 3e35b655.
Change-Id: I1accc7eb6fc6c64b5e27fb27d9e675ad523725b0
Signed-off-by: Mark Wu <wudxw(a)linux.vnet.ibm.com>
---
M tests/parted_utils_tests.py
1 file changed, 12 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/43/10843/1
diff --git a/tests/parted_utils_tests.py b/tests/parted_utils_tests.py
index 808d748..bb6bc8c 100644
--- a/tests/parted_utils_tests.py
+++ b/tests/parted_utils_tests.py
@@ -20,6 +20,7 @@
import tempfile
import os
+import rpm
import time
import testValidation
@@ -39,6 +40,15 @@
PART_SIZE_MB = 50
FREE_SIZE = 50 * ONE_MB_IN_BYTES
PART_END_SIZE = 47 * ONE_MB_IN_BYTES
+
+# parted 3.1 improves its support for loopback devices. The 'model' string
+# returned by libparted is updated to 'Loopback device'
+ts = rpm.TransactionSet()
+parted_version = float(list(ts.dbMatch('name', 'parted'))[0]['version'])
+if parted_version >= 3.1:
+ LOOP_DEVICE_MODEL = 'Loopback device'
+else:
+ LOOP_DEVICE_MODEL = ''
class PartedUtilsTests(TestCaseBase):
@@ -79,7 +89,7 @@
def _blank_dev_test(self):
info = putils.getDevicePartedInfo(self.devPath)
- self.assertFalse(info['model'])
+ self.assertEquals(info['model'], LOOP_DEVICE_MODEL)
self.assertTrue(info['sectorSize'] >= 0)
self.assertFalse(info['type'])
self.assertFalse(info['partitions'])
@@ -99,7 +109,7 @@
time.sleep(1) # wait for syncing
info = putils.getDevicePartedInfo(self.devPath)
- self.assertFalse(info['model'])
+ self.assertEquals(info['model'], LOOP_DEVICE_MODEL)
self.assertTrue(info['sectorSize'] >= 0)
self.assertEquals(info['type'], 'gpt')
self.assertTrue(info['freeSpaceRegions'][0][3] >= FREE_SIZE)
--
To view, visit http://gerrit.ovirt.org/10843
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1accc7eb6fc6c64b5e27fb27d9e675ad523725b0
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Mark Wu <wudxw(a)linux.vnet.ibm.com>
11 years, 5 months
Change in vdsm[ovirt-3.2]: vdsm.spec: BuildRequires: python-pthreading
by Douglas Schilling Landgraf
Douglas Schilling Landgraf has uploaded a new change for review.
Change subject: vdsm.spec: BuildRequires: python-pthreading
......................................................................
vdsm.spec: BuildRequires: python-pthreading
Moving python-pthreading to be a generic BuildRequirement
Change-Id: If996c366cac42e149193651d2d8a6dbde6d8c81e
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=891542
Signed-off-by: Douglas Schilling Landgraf <dougsland(a)redhat.com>
---
M vdsm.spec.in
1 file changed, 1 insertion(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/58/11058/1
diff --git a/vdsm.spec.in b/vdsm.spec.in
index b518045..14381e5 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -39,6 +39,7 @@
# BuildRequires needed by the tests during the build
BuildRequires: python-ethtool
+BuildRequires: python-pthreading
BuildRequires: libselinux-python
BuildRequires: libvirt-python
BuildRequires: genisoimage
--
To view, visit http://gerrit.ovirt.org/11058
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If996c366cac42e149193651d2d8a6dbde6d8c81e
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.2
Gerrit-Owner: Douglas Schilling Landgraf <dougsland(a)redhat.com>
11 years, 5 months
Change in vdsm[ovirt-3.2]: vdsm.spec: Don't require python-ordereddict on fedora
by Douglas Schilling Landgraf
Hello Mark Wu,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/11057
to review the following change.
Change subject: vdsm.spec: Don't require python-ordereddict on fedora
......................................................................
vdsm.spec: Don't require python-ordereddict on fedora
It is a regression introduced by commit bb0620f. The condition "0%{?rhel} < 7"
also holds true on fedora, so it causes to require python-ordereddict on fedora
Change-Id: I87e167f207669f4dda5bb71d7809fe301ea7e905
Signed-off-by: Mark Wu <wudxw(a)linux.vnet.ibm.com>
Signed-off-by: Douglas Schilling Landgraf <dougsland(a)redhat.com>
---
M vdsm.spec.in
1 file changed, 2 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/57/11057/1
diff --git a/vdsm.spec.in b/vdsm.spec.in
index c01d29f..b518045 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -44,7 +44,7 @@
BuildRequires: genisoimage
BuildRequires: openssl
BuildRequires: m2crypto
-%if 0%{?rhel} < 7
+%if 0%{?rhel} == 6
BuildRequires: python-ordereddict
%endif
@@ -174,7 +174,7 @@
BuildArch: noarch
Requires: %{name}-python = %{version}-%{release}
-%if 0%{?rhel} < 7
+%if 0%{?rhel} == 6
Requires: python-ordereddict
%endif
--
To view, visit http://gerrit.ovirt.org/11057
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I87e167f207669f4dda5bb71d7809fe301ea7e905
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.2
Gerrit-Owner: Douglas Schilling Landgraf <dougsland(a)redhat.com>
Gerrit-Reviewer: Mark Wu <wudxw(a)linux.vnet.ibm.com>
11 years, 5 months
Change in vdsm[ovirt-3.2]: vdsm.spec: python-ordereddict only for rhel < 7
by Douglas Schilling Landgraf
Douglas Schilling Landgraf has uploaded a new change for review.
Change subject: vdsm.spec: python-ordereddict only for rhel < 7
......................................................................
vdsm.spec: python-ordereddict only for rhel < 7
rhel7 contains python 2.7 which already includes ordereddict module,
no need extra python package.
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=891542
Change-Id: I784d82a7fb5a1c6a13f015747f077020b91c19cb
Signed-off-by: Douglas Schilling Landgraf <dougsland(a)redhat.com>
---
M vdsm.spec.in
1 file changed, 2 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/56/11056/1
diff --git a/vdsm.spec.in b/vdsm.spec.in
index f9e238b..c01d29f 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -44,7 +44,7 @@
BuildRequires: genisoimage
BuildRequires: openssl
BuildRequires: m2crypto
-%if 0%{?rhel}
+%if 0%{?rhel} < 7
BuildRequires: python-ordereddict
%endif
@@ -174,7 +174,7 @@
BuildArch: noarch
Requires: %{name}-python = %{version}-%{release}
-%if 0%{?rhel}
+%if 0%{?rhel} < 7
Requires: python-ordereddict
%endif
--
To view, visit http://gerrit.ovirt.org/11056
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I784d82a7fb5a1c6a13f015747f077020b91c19cb
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.2
Gerrit-Owner: Douglas Schilling Landgraf <dougsland(a)redhat.com>
11 years, 5 months
Change in vdsm[master]: Update except syntax according to pep3110.
by Dan Kenigsberg
Dan Kenigsberg has submitted this change and it was merged.
Change subject: Update except syntax according to pep3110.
......................................................................
Update except syntax according to pep3110.
The old except BlahException, e: is ambiguous and discouraged going
forward. The new syntax for python 3.x is supported since Python 2.6
and already present in our codebase, so it makes sense to
homogeinize our syntax. For more information:
http://www.python.org/dev/peps/pep-3110/
Change-Id: I2c4ac78dace34a41e1afb9f6560889ad9bd34ddf
Signed-off-by: Antoni S. Puimedon <asegurap(a)redhat.com>
---
M contrib/nfs-check.py
M tests/apiTests.py
M tests/miscTests.py
M vds_bootstrap/setup
M vds_bootstrap/vds_bootstrap.py
M vdsm/API.py
M vdsm/BindingXMLRPC.py
M vdsm/caps.py
M vdsm/clientIF.py
M vdsm/configNetwork.py
M vdsm/gluster/cli.py
M vdsm/kaxmlrpclib.py
M vdsm/libvirtconnection.py
M vdsm/libvirtvm.py
M vdsm/mkimage.py
M vdsm/netinfo.py
M vdsm/storage/blockSD.py
M vdsm/storage/blockVolume.py
M vdsm/storage/dispatcher.py
M vdsm/storage/domainMonitor.py
M vdsm/storage/fileSD.py
M vdsm/storage/fileUtils.py
M vdsm/storage/fileVolume.py
M vdsm/storage/hsm.py
M vdsm/storage/image.py
M vdsm/storage/imageRepository/formatConverter.py
M vdsm/storage/lvm.py
M vdsm/storage/misc.py
M vdsm/storage/remoteFileHandler.py
M vdsm/storage/resourceFactories.py
M vdsm/storage/resourceManager.py
M vdsm/storage/safelease.py
M vdsm/storage/sp.py
M vdsm/storage/storageServer.py
M vdsm/storage/storage_mailbox.py
M vdsm/storage/task.py
M vdsm/storage/taskManager.py
M vdsm/storage/volume.py
M vdsm/supervdsm.py
M vdsm/supervdsmServer.py
M vdsm/tc.py
M vdsm/utils.py
M vdsm/vm.py
M vdsm_api/BindingJsonRpc.py
M vdsm_api/Bridge.py
M vdsm_cli/vdsClient.py
M vdsm_reg/createDaemon.py
M vdsm_reg/deployUtil.py.in
M vdsm_reg/register-to-engine.py
M vdsm_reg/vdsm-reg-setup.in
M vdsm_reg/vdsm-upgrade
51 files changed, 199 insertions(+), 199 deletions(-)
Approvals:
Antoni Segura Puimedon: Verified
Dan Kenigsberg: Looks good to me, approved
--
To view, visit http://gerrit.ovirt.org/10942
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I2c4ac78dace34a41e1afb9f6560889ad9bd34ddf
Gerrit-PatchSet: 3
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Antoni Segura Puimedon <asegurap(a)redhat.com>
Gerrit-Reviewer: Antoni Segura Puimedon <asegurap(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Ewoud Kohl van Wijngaarden <ewoud(a)kohlvanwijngaarden.nl>
Gerrit-Reviewer: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
Gerrit-Reviewer: oVirt Jenkins CI Server
11 years, 5 months
Change in vdsm[master]: Update except syntax according to pep3110.
by Dan Kenigsberg
Dan Kenigsberg has posted comments on this change.
Change subject: Update except syntax according to pep3110.
......................................................................
Patch Set 3: Looks good to me, approved
Thanks!
--
To view, visit http://gerrit.ovirt.org/10942
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment
Gerrit-Change-Id: I2c4ac78dace34a41e1afb9f6560889ad9bd34ddf
Gerrit-PatchSet: 3
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Antoni Segura Puimedon <asegurap(a)redhat.com>
Gerrit-Reviewer: Antoni Segura Puimedon <asegurap(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Ewoud Kohl van Wijngaarden <ewoud(a)kohlvanwijngaarden.nl>
Gerrit-Reviewer: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
Gerrit-Reviewer: oVirt Jenkins CI Server
11 years, 5 months