def cluster_exec(self, cmd, single=False, parallel=False, all_nodes=False, check=False, timeout=None, **kwargs): """Runs cmd on cluster. If single is True, commands will run parallel, but only one command on server. If parallel is True, commands will run parallel and wouldn't see how many ones on one server. If both is false, one command per time. If all_nodes is true, runs command on all child of the node, else only on cluster (e.g. nodes with numeric name). If check is true, runs command only if all servers in node is alive. Optional argument is 'timeout', it's a timeout to determine if server is alive. See get_dead_nodes for detail. """ if single and parallel: raise TypeError("single OR parallel, not both") if (timeout is not None) and not check: raise TypeError("timeout hasn't got any sense without check=True") if check: if not alive.is_alive(self, all_nodes=all_nodes, **kwargs): raise RadistError('some nodes is dead') devnull = file(os.devnull, 'r') result = [] pids = {} queue = {} to_run = self.__get_exec_list(cmd, all_nodes) for node, command in to_run.items(): server = node.primary.server if parallel: pid = helpers.r_exec(server, command, flags=os.P_NOWAIT, stdin=devnull, **kwargs) pids[pid] = node elif single: if server not in queue: queue[server] = [] queue[server].append((node, command)) else: result.append((node, helpers.r_exec(server, command, **kwargs))) if parallel: return self.__wait_parallels(pids) elif single: return self.__run_single(queue, **kwargs) else: return result
def __run_single(self, queue, **kwargs): result = [] pids = {} for server in queue.keys(): node, command = queue[server].pop() pid = helpers.r_exec(server, command, flags=os.P_NOWAIT, **kwargs) pids[pid] = node while len(pids) > 0: pid, status = os.wait() if pid in pids: node = pids[pid] del pids[pid] result.append((node, status)) if len(queue[node.primary.server]) > 0: node, command = queue[node.primary.server].pop() server = node.primary.server pid = helpers.r_exec(server, command, flags=os.P_NOWAIT, **kwargs) pids[pid] = node else: # XXX shit happens pass return result
def r_exec(self, command, **kwargs): """Run command on node.""" return helpers.r_exec(self._get_server(), command % self.get_attrs(), **kwargs)