diff --git a/contrib/onelab2/python/onelab2.py b/contrib/onelab2/python/onelab2.py index a3e93bc7af7d5ab3a1f8e606362b3c2049de4f30..0a6a7f3168ef86e2eb1d49f9323f58af1c7c94f8 100755 --- a/contrib/onelab2/python/onelab2.py +++ b/contrib/onelab2/python/onelab2.py @@ -232,9 +232,28 @@ class client : print('onelab info : %s' % msg) return t, msg + def _parseParameter(msg): + def extract_attr(b): + t, l = struct.unpack('!HH', b[:4]) + if l+4 > len(b): + RuntimeError('onelab invalid parameter') + return t ,b[4:] + + ptype, p = extract_attr(msg) + if ptype == 0x06: + param = _parameter('number') + param.frombytes(msg) + return param + elif ptype == 0x07: + param = _parameter('string') + param.frombytes(msg) + return param + else: + return None + + def _getParameter(self, param, warn_if_not_found=True) : def extract_attr(b): - print(len(b)) t, l = struct.unpack('!HH', b[:4]) if l+4 > len(b): RuntimeError('onelab invalid parameter') @@ -246,8 +265,7 @@ class client : (t, msg) = self._receive() if t == self._ONELAB_RESPONSE : ptype, p = extract_attr(msg) - if ptype == 0x06 or ptype == 0x05: - print("recv") + if ptype == 0x06 or ptype == 0x07: param.frombytes(msg) elif ptype == 0x0A and warn_if_not_found: print('Unknown parameter %s' %(param.name)) @@ -270,14 +288,67 @@ class client : p.modify(**param) self._send(self._ONELAB_UPDATE, p.tobytes()) + def setString(self, name, **param): + if not self.socket : + return + p = _parameter('string', name=name) + self._getParameter(p, False) + p.modify(**param) + self._send(self._ONELAB_UPDATE, p.tobytes()) + def _sendMessage(self, msg, lvl=5): if not self.socket : print (msg) return self._send(self._ONELAB_MESSAGE, struct.pack("!HHB", 0x0A, len(msg)+1, lvl)+msg) + def sendFatal(self, msg) : + self._sendMessage(msg+'\0', 1) + def sendError(self, msg) : + self._sendMessage(msg+'\0', 2) + def sendWarning(self, msg) : + self._sendMessage(msg+'\0', 3) def sendInfo(self, msg) : - self._sendMessage(msg+'\0') + self._sendMessage(msg+'\0', 5) + def sendDebug(self, msg) : + self._sendMessage(msg+'\0', 99) + + def waitOnSubClient(self, name): + if not self.socket : + return + while self._numSubClients > 0: + (t, msg) = self._receive() + if t == _ONELAB_UPDATE: + param = _parseParameter(msg) + if param.type=='string' and param.name[-7:]=='/Action' and param.value=='stop': + if param.name[-7:] == name: return + self._numSubClients -= 1 # FIXME check that the client is a subclient ? + + + def waitOnSubClients(self): + if not self.socket : + return + while self._numSubClients > 0: + (t, msg) = self._receive() + if t == _ONELAB_UPDATE: + param = _parseParameter(msg) + if param.type=='string' and param.name[:-7]=='/Action' and param.value=='stop': + self._numSubClients -= 1 # FIXME check that the client is a subclient ? + + def runNonBlockingSubClient(self, name, command, arguments=''): + if self.action == 'check': + cmd = command + else: + cmd = command + ' ' + arguments + os.system(cmd); + self._numSubClients +=1 + self.getString(name+'/Action', False) + + def runSubClient(self, name, command, arguments=''): + self.runNonBlockingSubClient(name, command, arguments) + self.waitOnSubClient(name) # makes the subclient blocking + #if self.action == 'compute': + #TODO self.setChanged(name, False) def __init__(self, ref=''): self.socket = None @@ -306,12 +377,14 @@ class client : def finalize(self): # code aster python interpreter does not call the destructor at exit, it is # necessary to call finalize() epxlicitely + print("finalize") if self.socket : - #TODO self.waitOnSubClients() + self.waitOnSubClients() self._send(self._ONELAB_STOP) self._receive() self.socket.close() self.socket = None + print("finalize end") def __del__(self): self.finalize()