class NetTestSlave: def __init__(self, log_ctl, port = DefaultRPCPort): die_when_parent_die() self._cmd_context = NetTestCommandContext() self._server_handler = ServerHandler(("", port)) self._if_manager = InterfaceManager(self._server_handler) self._methods = SlaveMethods(self._cmd_context, log_ctl, self._if_manager) self.register_die_signal(signal.SIGHUP) self.register_die_signal(signal.SIGINT) self.register_die_signal(signal.SIGTERM) self._finished = False self._log_ctl = log_ctl self._server_handler.add_connection('netlink', self._if_manager.get_nl_socket()) def run(self): while not self._finished: if self._server_handler.get_ctl_sock() == None: self._log_ctl.cancel_connection() try: logging.info("Waiting for connection.") self._server_handler.accept_connection() except socket.error: continue self._log_ctl.set_connection( self._server_handler.get_ctl_sock()) msgs = self._server_handler.get_messages() for msg in msgs: self._process_msg(msg[1]) self._methods.machine_cleanup() def _process_msg(self, msg): if msg["type"] == "command": method = getattr(self._methods, msg["method_name"], None) if method != None: try: result = method(*msg["args"]) except: log_exc_traceback() type, value, tb = sys.exc_info() exc_trace = ''.join(traceback.format_exception(type, value, tb)) response = {"type": "exception", "Exception": value} self._server_handler.send_data_to_ctl(response) return if result != None: response = {"type": "result", "result": result} self._server_handler.send_data_to_ctl(response) else: err = "Method '%s' not supported." % msg["method_name"] response = {"type": "error", "err": err} self._server_handler.send_data_to_ctl(response) elif msg["type"] == "log": logger = logging.getLogger() record = logging.makeLogRecord(msg["record"]) logger.handle(record) elif msg["type"] == "exception": if msg["cmd_id"] != None: logging.debug("Recieved an exception from command with id: %s" % msg["cmd_id"]) else: logging.debug("Recieved an exception from foreground command") logging.debug(msg["Exception"]) cmd = self._cmd_context.get_cmd(msg["cmd_id"]) cmd.join() self._cmd_context.del_cmd(cmd) self._server_handler.send_data_to_ctl(msg) elif msg["type"] == "result": if msg["cmd_id"] == None: del msg["cmd_id"] self._server_handler.send_data_to_ctl(msg) cmd = self._cmd_context.get_cmd(None) cmd.join() self._cmd_context.del_cmd(cmd) else: cmd = self._cmd_context.get_cmd(msg["cmd_id"]) cmd.join() del msg["cmd_id"] cmd.set_result(msg["result"]) if cmd.finished(): msg["result"] = cmd.get_result() self._server_handler.send_data_to_ctl(msg) self._cmd_context.del_cmd(cmd) elif msg["type"] == "netlink": self._if_manager.handle_netlink_msgs(msg["data"]) else: raise Exception("Recieved unknown command") pipes = self._cmd_context.get_read_pipes() self._server_handler.update_connections(pipes) def register_die_signal(self, signum): signal.signal(signum, self._signal_die_handler) def _signal_die_handler(self, signum, frame): logging.info("Caught signal %d -> dying" % signum) self._finished = True
class NetTestSlave: def __init__(self, log_ctl, port=DefaultRPCPort): die_when_parent_die() self._cmd_context = NetTestCommandContext() self._netconfig = NetConfig() self._methods = SlaveMethods(self._cmd_context, self._netconfig, log_ctl) self.register_die_signal(signal.SIGHUP) self.register_die_signal(signal.SIGINT) self.register_die_signal(signal.SIGTERM) self._server_handler = ServerHandler(("", port)) self._finished = False self._log_ctl = log_ctl def run(self): while not self._finished: if self._server_handler.get_ctl_sock() == None: self._log_ctl.cancel_connection() logging.info("Waiting for connection, performing cleanup.") logging.info("Cleaning up leftover commands.") self._cmd_context.cleanup() logging.info("Cleaning up configured interfaces.") self._netconfig.deconfigure_all() self._netconfig.cleanup() try: self._server_handler.accept_connection() except socket.error: continue self._cmd_context.cleanup() self._log_ctl.set_connection( self._server_handler.get_ctl_sock()) msgs = self._server_handler.get_messages() for msg in msgs: self._process_msg(msg[1]) logging.info("Cleaning up leftover commands.") self._cmd_context.cleanup() logging.info("Cleaning up configured interfaces.") self._netconfig.deconfigure_all() self._netconfig.cleanup() def _process_msg(self, msg): if msg["type"] == "command": method = getattr(self._methods, msg["method_name"], None) if method != None: try: result = method(*msg["args"]) except: log_exc_traceback() type, value, tb = sys.exc_info() exc_trace = ''.join( traceback.format_exception(type, value, tb)) response = {"type": "exception", "Exception": exc_trace} self._server_handler.send_data_to_ctl(response) return if result != None: response = {"type": "result", "result": result} self._server_handler.send_data_to_ctl(response) else: err = "Method '%s' not supported." % msg["method_name"] response = {"type": "error", "err": err} self._server_handler.send_data_to_ctl(response) elif msg["type"] == "log": logger = logging.getLogger() record = logging.makeLogRecord(msg["record"]) logger.handle(record) elif msg["type"] == "exception": if msg["cmd_id"] != None: logging.debug( "Recieved an exception from command with id: %s" % msg["cmd_id"]) else: logging.debug("Recieved an exception from foreground command") logging.error(msg["Exception"]) cmd = self._cmd_context.get_cmd(msg["cmd_id"]) cmd.join() self._cmd_context.del_cmd(cmd) self._server_handler.send_data_to_ctl(msg) elif msg["type"] == "result": if msg["cmd_id"] == None: del msg["cmd_id"] self._server_handler.send_data_to_ctl(msg) cmd = self._cmd_context.get_cmd(None) cmd.join() self._cmd_context.del_cmd(cmd) else: cmd = self._cmd_context.get_cmd(msg["cmd_id"]) cmd.join() del msg["cmd_id"] if cmd.finished(): self._server_handler.send_data_to_ctl(msg) self._cmd_context.del_cmd(cmd) else: cmd.set_result(msg["result"]) else: raise Exception("Recieved unknown command") pipes = self._cmd_context.get_read_pipes() self._server_handler.update_connections(pipes) def register_die_signal(self, signum): signal.signal(signum, self._signal_die_handler) def _signal_die_handler(self, signum, frame): logging.info("Caught signal %d -> dying" % signum) self._finished = True
class NetTestSlave: def __init__(self, log_ctl): die_when_parent_die() self._cmd_context = NetTestCommandContext() port = lnst_config.get_option("environment", "rpcport") logging.info("Using RPC port %d." % port) self._server_handler = ServerHandler(("", port)) self._if_manager = InterfaceManager(self._server_handler) self._server_handler.set_if_manager(self._if_manager) self._net_namespaces = {} self._methods = SlaveMethods(self._cmd_context, log_ctl, self._if_manager, self._net_namespaces, self._server_handler, self) self.register_die_signal(signal.SIGHUP) self.register_die_signal(signal.SIGINT) self.register_die_signal(signal.SIGTERM) self._finished = False self._log_ctl = log_ctl self._server_handler.add_connection('netlink', self._if_manager.get_nl_socket()) def run(self): while not self._finished: if self._server_handler.get_ctl_sock() == None: self._log_ctl.cancel_connection() try: logging.info("Waiting for connection.") self._server_handler.accept_connection() except (socket.error, SecSocketException): continue self._log_ctl.set_connection( self._server_handler.get_ctl_sock()) msgs = self._server_handler.get_messages() for msg in msgs: self._process_msg(msg[1]) self._methods.machine_cleanup() def wait_for_result(self, id): result = None while result == None: msgs = self._server_handler.get_messages_from_con(id) for msg in msgs: if msg[1]["type"] == "result": result = msg[1] elif msg[1]["type"] == "from_netns" and\ msg[1]["data"]["type"] == "result": result = msg[1]["data"] else: self._process_msg(msg[1]) return result def _process_msg(self, msg): if msg["type"] == "command": method = getattr(self._methods, msg["method_name"], None) if method != None: try: result = method(*msg["args"]) except: log_exc_traceback() type, value, tb = sys.exc_info() exc_trace = ''.join( traceback.format_exception(type, value, tb)) response = {"type": "exception", "Exception": value} self._server_handler.send_data_to_ctl(response) return if result != None: response = {"type": "result", "result": result} self._server_handler.send_data_to_ctl(response) else: err = "Method '%s' not supported." % msg["method_name"] response = {"type": "error", "err": err} self._server_handler.send_data_to_ctl(response) elif msg["type"] == "log": logger = logging.getLogger() record = logging.makeLogRecord(msg["record"]) logger.handle(record) elif msg["type"] == "exception": if msg["cmd_id"] != None: logging.debug( "Recieved an exception from command with id: %s" % msg["cmd_id"]) else: logging.debug("Recieved an exception from foreground command") logging.debug(msg["Exception"]) cmd = self._cmd_context.get_cmd(msg["cmd_id"]) cmd.join() self._cmd_context.del_cmd(cmd) self._server_handler.send_data_to_ctl(msg) elif msg["type"] == "result": if msg["cmd_id"] == None: del msg["cmd_id"] self._server_handler.send_data_to_ctl(msg) cmd = self._cmd_context.get_cmd(None) cmd.join() cmd.set_result_sent() else: cmd = self._cmd_context.get_cmd(msg["cmd_id"]) cmd.join() del msg["cmd_id"] cmd.set_result(msg["result"]) if cmd.finished(): msg["result"] = cmd.get_result() self._server_handler.send_data_to_ctl(msg) cmd.set_result_sent() elif msg["type"] == "netlink": self._if_manager.handle_netlink_msgs(msg["data"]) elif msg["type"] == "from_netns": self._server_handler.send_data_to_ctl(msg["data"]) elif msg["type"] == "to_netns": netns = msg["netns"] try: self._server_handler.send_data_to_netns(netns, msg["data"]) except: log_exc_traceback() type, value, tb = sys.exc_info() exc_trace = ''.join(traceback.format_exception( type, value, tb)) response = {"type": "exception", "Exception": value} self._server_handler.send_data_to_ctl(response) return else: raise Exception("Recieved unknown command") pipes = self._cmd_context.get_read_pipes() self._server_handler.update_connections(pipes) def register_die_signal(self, signum): signal.signal(signum, self._signal_die_handler) def _signal_die_handler(self, signum, frame): logging.info("Caught signal %d -> dying" % signum) self._finished = True def _parent_resend_signal_handler(self, signum, frame): logging.info("Caught signal %d -> resending to parent" % signum) os.kill(os.getppid(), signum) def set_netns_sighandlers(self): signal.signal(signal.SIGHUP, self._parent_resend_signal_handler) signal.signal(signal.SIGINT, self._parent_resend_signal_handler) signal.signal(signal.SIGTERM, self._parent_resend_signal_handler) signal.signal(signal.SIGUSR1, self._signal_die_handler)