예제 #1
0
def stop_daemon():
    """
        Method for stopping the daemon and unregistering the daemon at the nameservice
    :return:
    """
    llogger = local_logger.LocalLogger()
    llogger.log_call(sys._getframe().f_code.co_name)
    params = CMDParser(program_path="daemon stop",
                       description="Stop the swarmrob daemon.",
                       arguments=[Argument.INTERFACE]).parse_arguments()
    try:
        network_info = network.NetworkInfo(params.interface)
    except NetworkException:
        puts(
            colored.red(
                "Host interface not valid. Specify a different host interface."
            ))
        puts(
            colored.red("Possible options are: " +
                        " ".join(network.get_interface_list())))
        llogger.debug(
            "Missing host interface. Add one with option --interface.")
        return

    try:
        proxy = pyro_interface.get_daemon_proxy(network_info.ip_address)
        if proxy.is_daemon_running():
            pid = proxy.shutdown(network_info.ip_address)
            os.kill(pid, signal.SIGINT)
        else:
            puts(colored.red("Daemon is not running"))
            llogger.debug("Status Daemon: Daemon is not running")
    except NetworkException as e:
        puts(colored.red(str(e)))
예제 #2
0
def join_swarm():
    """
        Abstracts the join_swarm command on the worker CLI
    :return:
    """
    llogger = local_logger.LocalLogger()
    llogger.log_call(sys._getframe().f_code.co_name)
    puts(colored.yellow("Join swarm"))
    params = CMDParser(program_path="worker join", description="Join a swarm as a worker.",
                       arguments=[Argument.INTERFACE, Argument.UUID]).parse_arguments()

    if '@' not in params.uuid:
        puts(colored.red("Invalid uuid. Correct syntax is <uuid>@<ns_uri>."))
        llogger.debug("Invalid uuid. Correct syntax is <uuid>@<ns_uri>.")
        return

    swarm_uuid = str(params.uuid).split("@")[0]
    nameservice_uri = str(params.uuid).split("@")[1]

    try:
        network_info = network.NetworkInfo(params.interface)
    except NetworkException:
        puts(colored.red("Host interface not valid. Specify a different host interface."))
        puts(colored.red("Possible options are: " + " ".join(network.get_interface_list())))
        llogger.debug("Missing host interface. Add one with option --interface.")
        return

    try:
        proxy = pyro_interface.get_daemon_proxy(network_info.ip_address)
        proxy.register_worker(swarm_uuid, nameservice_uri)
    except NetworkException as e:
        puts(colored.red(str(e)))
        daemon.check_daemon_running(network_info.interface)
예제 #3
0
 def test_local_network_info(self):
     try:
         network_info = network.NetworkInfo("lo")
         self.assertEqual(network_info.interface, "lo")
         self.assertEqual(network_info.ip_address, "127.0.0.1")
     except errors.NetworkException:
         self.fail(msg="Unable to create localhost network info object")
예제 #4
0
 def __init__(self, interface=None):
     if not os.path.exists(SWARM_LOGFILE_PATH):
         os.makedirs(SWARM_LOGFILE_PATH)
     network_info = network.NetworkInfo(interface)
     self.interface = network_info.interface
     self.tcp_server = LogRecordSocketReceiver(host=network_info.ip_address)
     self.hostname = self.tcp_server.socket.getsockname()[0]
     self.port = self.tcp_server.socket.getsockname()[1]
     threading.Thread.__init__(self)
예제 #5
0
 def test_none(self):
     try:
         network_info = network.NetworkInfo(None)
         default_interface = network.get_default_interface()
         self.assertEqual(network_info.interface, default_interface)
         self.assertEqual(network_info.ip_address,
                          network.get_ip_of_interface(default_interface))
     except errors.NetworkException:
         self.fail(msg="Unable to create default network info object")
예제 #6
0
def worker_status():
    """
        The status of a specific worker. The worker can be defined by
        --worker_uuid and represented as a table
    :return:
    """
    llogger = local_logger.LocalLogger()
    llogger.log_call(sys._getframe().f_code.co_name)
    params = CMDParser(program_path="master worker_status",
                       description="Print the status of a single worker.",
                       arguments=[Argument.INTERFACE,
                                  Argument.WORKER_UUID]).parse_arguments()

    try:
        network_info = network.NetworkInfo(params.interface)
    except NetworkException:
        puts(
            colored.red(
                "Host interface not valid. Specify a different host interface."
            ))
        puts(
            colored.red("Possible options are: " +
                        " ".join(network.get_interface_list())))
        llogger.debug(
            "Missing host interface. Add one with option --interface.")
        return

    try:
        swarmrob_daemon_proxy = pyro_interface.get_daemon_proxy(
            network_info.ip_address)
    except NetworkException as e:
        puts(colored.red(str(e)))
        daemon.check_daemon_running(network_info.interface)
        return

    swarm_info = jsonpickle.decode(
        swarmrob_daemon_proxy.get_swarm_status_as_json())
    worker_list = list(dict(swarm_info._worker_list).items())

    worker_info = None
    for _, worker_list_val in worker_list:
        worker = jsonpickle.decode(worker_list_val.get_info_as_json())
        if str(worker.uuid) == params.worker_uuid:
            worker_info = worker

    if worker_info is None:
        puts(colored.red("No worker found with id " + params.worker_uuid))
        return

    print(table_builder.worker_status_to_table(worker_info))
    print(table_builder.service_list_to_table(worker_info))
예제 #7
0
def start_daemon(interface=None):
    """
        Method for starting and registering the daemon at the nameservice
    :return:
    """
    llogger = local_logger.LocalLogger()
    llogger.log_call(sys._getframe().f_code.co_name)
    params = CMDParser(program_path="daemon start",
                       description="Start the swarmrob daemon.",
                       arguments=[Argument.INTERFACE,
                                  Argument.DAEMONIZE]).parse_arguments()

    ret_code = 0
    if params.daemonize:
        ret_code = process_helper.create_daemon()
    os.chdir('/')
    log_pid()
    host_interface = params.interface
    if host_interface is None:
        host_interface = interface
    try:
        network_info = network.NetworkInfo(host_interface)
    except NetworkException:
        puts(
            colored.red(
                "Host interface not valid. Specify a different host interface."
            ))
        puts(
            colored.red("Possible options are: " +
                        " ".join(network.get_interface_list())))
        llogger.debug(
            "Missing host interface. Add one with option --interface.")
        return

    pyro_nameservice_object = pyro_interface.get_name_service(
        network_info.ip_address, start=True)
    pyro_interface.clear_name_service(pyro_nameservice_object)
    with Pyro4.Daemon(host=network_info.ip_address,
                      port=WORKER_PORT) as pyro_daemon:
        daemon_uri = pyro_daemon.register(
            swarmrob_d.SwarmRobDaemon(network_info.interface, pyro_daemon))
        pyro_nameservice_object.register(pyro_interface.SWARMROBD_IDENTIFIER,
                                         daemon_uri)
        signal.signal(signal.SIGINT, signal_handler_shutdown)
        llogger.debug("Daemon started. Object URI = %s", daemon_uri)
        puts(colored.green("Daemon started. Object URI = " + str(daemon_uri)))
        pyro_daemon.requestLoop(swarmrob_d.SwarmRobDaemon().is_daemon_running)
    sys.exit(ret_code)
예제 #8
0
def leave_swarm():
    """
        Command to remove the worker from the swarm
    :return:
    """
    llogger = local_logger.LocalLogger()
    llogger.log_call(sys._getframe().f_code.co_name)
    puts(colored.yellow("Leave swarm"))
    params = CMDParser(program_path="worker leave", description="Leave a swarm.",
                       arguments=[Argument.INTERFACE, Argument.SWARM_UUID, Argument.UUID]).parse_arguments()

    if '@' not in params.uuid:
        puts(colored.red("Invalid swarm uuid. Correct syntax is <uuid>@<ns_uri>."))
        llogger.debug("Invalid swarm uuid. Correct syntax is <uuid>@<ns_uri>.")
        return

    swarm_uuid = str(params.swarm_uuid).split("@")[0]
    nameservice_uri = str(params.swarm_uuid).split("@")[1]
    worker_uuid = str(params.uuid)

    try:
        network_info = network.NetworkInfo(params.interface)
    except NetworkException:
        puts(colored.red("Host interface not valid. Specify a different host interface."))
        puts(colored.red("Possible options are: " + " ".join(network.get_interface_list())))
        llogger.debug("Missing host interface. Add one with option --interface.")
        return

    try:
        proxy = pyro_interface.get_daemon_proxy(network_info.ip_address)
        removed = proxy.unregister_worker(swarm_uuid, nameservice_uri, worker_uuid)
        if removed:
            puts("Successfully removed worker with uuid " + worker_uuid + " from swarm " + swarm_uuid)
            llogger.debug("Successfully removed worker with uuid %s from swarm %s", worker_uuid, swarm_uuid)
        else:
            puts(colored.red("Failed to remove worker with uuid " + worker_uuid + " from swarm " + swarm_uuid))
            llogger.error("Failed to remove worker with uuid %s from swarm %s", worker_uuid, swarm_uuid)
    except NetworkException as e:
        puts(colored.red(str(e)))
        daemon.check_daemon_running(network_info.interface)
예제 #9
0
def swarm_status():
    """
        The status of the swarm (advertise address, uuid, worker list, ...). The swarm is represented as a table
    :return:
    """
    llogger = local_logger.LocalLogger()
    llogger.log_call(sys._getframe().f_code.co_name)
    params = CMDParser(program_path="master swarm_status",
                       description="Print the status of the swarm.",
                       arguments=[Argument.INTERFACE]).parse_arguments()

    try:
        network_info = network.NetworkInfo(params.interface)
    except NetworkException:
        puts(
            colored.red(
                "Host interface not valid. Specify a different host interface."
            ))
        puts(
            colored.red("Possible options are: " +
                        " ".join(network.get_interface_list())))
        llogger.debug(
            "Missing host interface. Add one with option --interface.")
        return

    try:
        swarmrob_daemon_proxy = pyro_interface.get_daemon_proxy(
            network_info.ip_address)
        swarm_status_as_json = swarmrob_daemon_proxy.get_swarm_status_as_json()
        print(
            table_builder.swarm_status_to_table(
                jsonpickle.decode(swarm_status_as_json)))
        print(
            table_builder.swarm_status_to_worker_list(
                jsonpickle.decode(swarm_status_as_json)))
    except NetworkException as e:
        puts(colored.red(str(e)))
        daemon.check_daemon_running(network_info.interface)
예제 #10
0
def status_daemon():
    """
        Method for showing the status of the daemon at the daemon CLI
    :return:
    """
    llogger = local_logger.LocalLogger()
    llogger.log_call(sys._getframe().f_code.co_name)
    params = CMDParser(program_path="daemon status",
                       description="Print the daemon status.",
                       arguments=[Argument.INTERFACE]).parse_arguments()
    try:
        network_info = network.NetworkInfo(params.interface)
    except NetworkException:
        puts(
            colored.red(
                "Host interface not valid. Specify a different host interface."
            ))
        puts(
            colored.red("Possible options are: " +
                        " ".join(network.get_interface_list())))
        llogger.debug(
            "Missing host interface. Add one with option --interface.")
        return

    try:
        proxy = pyro_interface.get_daemon_proxy(network_info.ip_address)
        if proxy.is_daemon_running():
            daemon_mode = jsonpickle.decode(proxy.get_mode())
            puts(
                colored.green("Daemon is running and in mode: " +
                              str(daemon_mode.value)))
            llogger.debug("Status Daemon: Daemon is running in mode: %s",
                          str(daemon_mode.value))
        else:
            puts(colored.red("Daemon is not running"))
            llogger.debug("Status Daemon: Daemon is not running")
    except NetworkException as e:
        puts(colored.red(str(e)))
예제 #11
0
def check_daemon_running(interface=None):
    llogger = local_logger.LocalLogger()
    llogger.log_call(sys._getframe().f_code.co_name)
    # Check if daemon is running and start it
    try:
        try:
            network_info = network.NetworkInfo(interface)
        except NetworkException:
            puts(
                colored.red(
                    "Host interface not valid. Specify a different host interface."
                ))
            puts(
                colored.red("Possible options are: " +
                            " ".join(network.get_interface_list())))
            return
        pyro_interface.get_daemon_proxy(network_info.ip_address)
        puts(colored.green("Daemon running"))
    except NetworkException:
        puts(colored.red("Daemon not running"))
        result = cmd_helper.query_yes_no("Start daemon?")
        if result:
            start_daemon(interface)
예제 #12
0
def status_worker():
    """
        Shows the status of the worker on the CLI
    :return:
    """
    llogger = local_logger.LocalLogger()
    llogger.log_call(sys._getframe().f_code.co_name)
    params = CMDParser(program_path="worker status", description="Show the status of the worker.",
                       arguments=[Argument.INTERFACE]).parse_arguments()
    try:
        network_info = network.NetworkInfo(params.interface)
    except NetworkException:
        puts(colored.red("Host interface not valid. Specify a different host interface."))
        puts(colored.red("Possible options are: " + " ".join(network.get_interface_list())))
        llogger.debug("Missing host interface. Add one with option --interface.")
        return

    try:
        proxy = pyro_interface.get_daemon_proxy(network_info.ip_address)
        worker_status_as_json = proxy.get_worker_status_as_json()
        print(table_builder.worker_daemon_status_to_table(jsonpickle.decode(worker_status_as_json)))
    except NetworkException as e:
        puts(colored.red(str(e)))
        daemon.check_daemon_running(network_info.interface)
예제 #13
0
 def test_default_network_info(self):
     try:
         network.NetworkInfo()
     except errors.NetworkException:
         self.fail(msg="Unable to create default network info object")
예제 #14
0
def start_swarm_by_compose_file():
    """
        Starts a predefined swarm based on a docker compose file.
    :return:
    """
    llogger = local_logger.LocalLogger()
    llogger.log_call(sys._getframe().f_code.co_name)
    params = CMDParser(program_path="master start_swarm",
                       description="Run an EDF file inside a swarm.",
                       arguments=[
                           Argument.INTERFACE, Argument.UUID,
                           Argument.COMPOSE_FILE, Argument.LOG_FOLDER,
                           Argument.LOG_IDENTIFIER
                       ]).parse_arguments()

    try:
        network_info = network.NetworkInfo(params.interface)
    except NetworkException:
        puts(
            colored.red(
                "Host interface not valid. Specify a different host interface."
            ))
        puts(
            colored.red("Possible options are: " +
                        " ".join(network.get_interface_list())))
        llogger.debug(
            "Missing host interface. Add one with option --interface.")
        return

    try:
        swarm_composition = edf_parser.create_service_composition_from_edf(
            params.compose_file)
    except IOError:
        llogger.error("Unable to load compose file: %s", params.compose_file)
        puts(colored.red("Unable to load compose file: " +
                         params.compose_file))
        return

    llogger.debug("Try to start swarm: %s with the following composition",
                  params.uuid)
    llogger.debug("\n" +
                  swarm_composition.format_service_composition_as_table())
    puts("Try to start swarm: " + params.uuid +
         " with the following composition")
    puts("\n" + swarm_composition.format_service_composition_as_table())

    try:
        swarmrob_daemon_proxy = pyro_interface.get_daemon_proxy(
            network_info.ip_address)
    except NetworkException as e:
        puts(colored.red(str(e)))
        daemon.check_daemon_running(network_info.interface)
        return

    if params.log_identifier is not None or params.log_folder is not None:
        swarmrob_daemon_proxy.configure_evaluation_logger(
            params.log_folder, params.log_identifier, True)
    swarmrob_daemon_proxy.reset_evaluation_logger()

    try:
        swarmrob_daemon_proxy.start_swarm_by_composition(
            jsonpickle.encode(swarm_composition), params.uuid)
        puts(colored.yellow("Successfully started swarm"))
    except RuntimeError as e:
        puts("Error while starting swarm")
        llogger.exception(e, "Error while starting swarm")
예제 #15
0
def init_swarm():
    """
        Initializes a swarm and starts a master on the predefined advertise address. The uuid of the
        swarm is randomly generated at runtime or can be specified with --swarm_uuid (Hint: Only for Development)
    :return:
    """
    llogger = local_logger.LocalLogger()
    llogger.log_call(sys._getframe().f_code.co_name)
    new_swarm = None
    params = CMDParser(
        program_path="master init",
        description="Initialize the swarm by creating a master node.",
        arguments=[
            Argument.ADVERTISE_ADDRESS, Argument.INTERFACE,
            Argument.UUID_OPTIONAL
        ]).parse_arguments()

    try:
        network_info = network.NetworkInfo(params.interface)
    except NetworkException:
        puts(
            colored.red(
                "Host interface not valid. Specify a different host interface."
            ))
        puts(
            colored.red("Possible options are: " +
                        " ".join(network.get_interface_list())))
        llogger.debug(
            "Missing host interface. Add one with option --interface.")
        return

    if params.advertise_address is None:
        params.advertise_address = network_info.ip_address
        puts("Missing advertise address. Using advertise address " +
             str(params.advertise_address) + " given by interface.")
        llogger.debug("Missing advertise address. Using advertise address " +
                      str(params.advertise_address) + " given by interface.")

    puts(colored.yellow("Init swarm on " + params.advertise_address))
    llogger.debug("Init swarm on: %s and interface: %s",
                  params.advertise_address, network_info.interface)

    try:
        swarmrob_daemon_proxy = pyro_interface.get_daemon_proxy(
            network_info.ip_address)
        sys.setrecursionlimit(RECURSION_LIMIT)

        new_swarm = jsonpickle.decode(
            swarmrob_daemon_proxy.create_new_swarm(
                params.advertise_address,
                network_info.interface,
                predefined_uuid=params.uuid))
    except RuntimeError as e:
        puts(colored.red(str(e)))
        llogger.exception(str(e))
    except NetworkException as e:
        puts(colored.red(str(e)))
        daemon.check_daemon_running(network_info.interface)
    except (Pyro4.errors.DaemonError, Pyro4.errors.CommunicationError) as e:
        puts(colored.red("A daemon related error occurred - " + str(e)))
        llogger.error("A daemon related error occurred - " + str(e))
        llogger.exception(traceback.format_exc())
        daemon.check_daemon_running(network_info.interface)
    if new_swarm is not None:
        puts(
            colored.yellow(
                "Swarm created: Type 'swarmrob worker join --uuid " +
                str(new_swarm.uuid) + "@" + str(new_swarm.advertise_address) +
                "' on the node to join the swarm"))
        llogger.debug("Swarm created: Type 'swarmrob worker join --uuid " +
                      str(new_swarm.uuid) + "@" +
                      str(new_swarm.advertise_address) +
                      "' on the node to join the swarm")

    else:
        llogger.error("Can't create the swarm")
        puts(colored.red("Can't create the swarm"))