コード例 #1
0
def save_recent_session(session_key, argv):
    """
    Saves session arguments into recents file.

    :param session_key: key to save under (only one session per key is saved)
    :param argv:        argument list to save
    :return:            None
    """
    # add current line to history, if not already there
    cmdline = " ".join(
        [x if x and not ' ' in x else "'{}'".format(x) for x in argv])
    if not _last_input:
        if cmdline != readline.get_history_item(
                readline.get_current_history_length()):
            readline.add_history(cmdline)

    make_radiopadre_dir()
    try:
        readline.write_history_file(HISTORY_FILE)
    except IOError:
        traceback.print_exc()
        warning("Error writing history file (see above). Proceeding anyway.")

    readline.clear_history()

    # reform command-line without persisting options
    cmdline = " ".join([
        x if x and not ' ' in x else "'{}'".format(x) for x in argv
        if x not in config.NON_PERSISTING_OPTIONS
    ])

    recents = _load_recent_sessions(False) or OrderedDict()
    session_key = ":".join(map(str, session_key))
    if session_key in recents:
        del recents[session_key]
    if len(recents) >= 5:
        del recents[list(recents.keys())[0]]
    recents[session_key] = cmdline

    make_radiopadre_dir()
    with open(RECENTS_FILE, 'wt') as rf:
        for key, cmdline in recents.items():
            rf.write("{}:::{}\n".format(key, cmdline))

    global _recent_sessions
    _recent_sessions = recents
コード例 #2
0
ファイル: config.py プロジェクト: ratt-ru/radiopadre-client
def init_specific_options(remote_host, notebook_path, options):
    global _DEFAULT_KEYS
    global _CMDLINE_DEFAULTS
    parser = configparser.ConfigParser()
    hostname = ff("{remote_host}") if remote_host else "local sesssion"
    session = ff("{hostname}:{notebook_path}")
    config_exists = os.path.exists(CONFIG_FILE)
    use_config_files = not options.remote and not options.inside_container

    # try to read config file for host and host:path (not in --remote mode though)
    if use_config_files and config_exists:
        parser.read(CONFIG_FILE)
        for sect_key in "global defaults", hostname, session:
            if parser.has_section(sect_key):
                section = dict(parser.items(sect_key))
                if section:
                    message(
                        ff("  loading settings from {CONFIG_FILE} [{sect_key}]"
                           ))
                    for key in _DEFAULT_KEYS:
                        lkey = key.lower()
                        if lkey in section:
                            value = _get_config_value(section, lkey)
                            if value != globals()[key]:
                                message(ff("    {key} = {value}"))
                                globals()[key] = value

    # update using command-line options
    command_line_updated = []
    for key in globals().keys():
        if re.match("^[A-Z]", key):
            optname = key.lower()
            opt_switch = "--" + optname.replace("_", "-")
            value = getattr(options, optname, None)
            # skip DEFAULT_VALUE placeholders, trust in config
            if value is DEFAULT_VALUE or value is None:
                continue
            if type(value) is list:
                value = ",".join(value)
            if value is not _CMDLINE_DEFAULTS.get(key, None):
                if use_config_files:
                    # do not mark options such as --update for saving
                    if value is not _CMDLINE_DEFAULTS.get(key) and DefaultConfig.get(key) is not None \
                                and opt_switch not in NON_PERSISTING_OPTIONS:
                        command_line_updated.append(key)
                    message(ff("  command line specifies {key} = {value}"))
                globals()[key] = value

    # save new config
    if use_config_files and command_line_updated:
        if options.save_config_host:
            message(
                ff("  saving command-line settings to {CONFIG_FILE} [{hostname}]"
                   ))
            if not parser.has_section(hostname):
                parser.add_section(hostname)
            for key in command_line_updated:
                parser.set(hostname, key, _set_config_value(key))
        if options.save_config_session:
            if not parser.has_section(session):
                parser.add_section(session)
            message(
                ff("  saving command-line settings to {CONFIG_FILE} [{session}]"
                   ))
            for key in command_line_updated:
                parser.set(session, key, _set_config_value(key))

        if options.save_config_host or options.save_config_session:
            radiopadre_dir = make_radiopadre_dir()
            with open(CONFIG_FILE + ".new", "w") as configfile:
                if not config_exists:
                    message(ff("  creating new config file {CONFIG_FILE}"))
                if not parser.has_section('global defaults'):
                    configfile.write(
                        "[global defaults]\n# defaults that apply to all sessions go here\n\n"
                    )

                parser.write(configfile)

                configfile.write("\n\n## default settings follow\n")
                for key, value in DefaultConfig.items():
                    configfile.write("# {} = {}\n".format(key.lower(), value))

            # if successful, rename files
            if config_exists:
                if os.path.exists(CONFIG_FILE + ".old"):
                    os.unlink(CONFIG_FILE + ".old")
                os.rename(CONFIG_FILE, CONFIG_FILE + ".old")
            os.rename(CONFIG_FILE + ".new", CONFIG_FILE)

            message(ff("saved updated config to {CONFIG_FILE}"))
コード例 #3
0
def _init_session_dir():
    radiopadre_dir = make_radiopadre_dir()
    global SESSION_INFO_DIR
    SESSION_INFO_DIR = ff("{radiopadre_dir}/sessions")
    make_dir(SESSION_INFO_DIR)
コード例 #4
0
def start_session(container_name, selected_ports, userside_ports,
                  notebook_path, browser_urls):
    from iglesia import ABSROOTDIR, LOCAL_SESSION_DIR, SHADOW_SESSION_DIR, SNOOP_MODE
    radiopadre_dir = make_radiopadre_dir()
    docker_local = make_dir(radiopadre_dir + "/.docker-local")
    js9_tmp = make_dir(radiopadre_dir + "/.js9-tmp")
    session_info_dir = get_session_info_dir(container_name)

    message(
        ff("Container name: {container_name}"))  # remote script will parse it

    docker_opts = [
        docker,
        "run",
        "--rm",
        "--name",
        container_name,
        "--cap-add=SYS_ADMIN",
        "-w",
        ABSROOTDIR,
        "--user",
        "{}:{}".format(os.getuid(), os.getgid()),
        "-e",
        "USER={}".format(os.environ["USER"]),
        "-e",
        "HOME={}".format(os.environ["HOME"]),
        "-e",
        "RADIOPADRE_DIR={}".format(radiopadre_dir),
        "-e",
        ff("RADIOPADRE_CONTAINER_NAME={container_name}"),
        "-e",
        ff("RADIOPADRE_SESSION_ID={config.SESSION_ID}"),
    ]
    # enable detached mode if not debugging, and also if not doing conversion non-interactively
    if not config.CONTAINER_DEBUG and not config.NBCONVERT:
        docker_opts.append("-d")
    for port1, port2 in zip(selected_ports, CONTAINER_PORTS):
        docker_opts += ["-p", "{}:{}/tcp".format(port1, port2)]
    container_ports = list(CONTAINER_PORTS)
    # setup mounts for work dir and home dir, if needed
    homedir = os.path.expanduser("~")
    docker_opts += [
        "-v",
        "{}:{}{}".format(ABSROOTDIR, ABSROOTDIR, ":ro" if SNOOP_MODE else ""),
        "-v",
        "{}:{}".format(homedir, homedir),
        "-v",
        "{}:{}".format(radiopadre_dir, radiopadre_dir),
        ## hides /home/user/.local, which can confuse jupyter and ipython
        ## into seeing e.g. kernelspecs that they should not see
        "-v",
        "{}:{}/.local".format(docker_local, homedir),
        # mount session info directory (needed to serve e.g. js9prefs.js)
        "-v",
        "{}:{}".format(session_info_dir, LOCAL_SESSION_DIR),
        "-v",
        "{}:{}".format(session_info_dir, SHADOW_SESSION_DIR),
        # mount a writeable tmp dir for the js9 install -- needed by js9helper
        "-v",
        "{}:/.radiopadre/venv/js9-www/tmp".format(js9_tmp),
        "--label",
        "radiopadre.user={}".format(USER),
        "--label",
        "radiopadre.dir={}".format(os.getcwd()),
    ]
    if config.CONTAINER_DEV:
        if os.path.isdir(SERVER_INSTALL_PATH):
            docker_opts += ["-v", "{}:/radiopadre".format(SERVER_INSTALL_PATH)]
        if os.path.isdir(CLIENT_INSTALL_PATH):
            docker_opts += [
                "-v", "{}:/radiopadre-client".format(CLIENT_INSTALL_PATH)
            ]
    # add image
    docker_opts.append(docker_image)

    # build up command-line arguments
    docker_opts += _collect_runscript_arguments(container_ports +
                                                userside_ports)

    if notebook_path:
        docker_opts.append(notebook_path)

    _run_container(container_name,
                   docker_opts,
                   jupyter_port=selected_ports[0],
                   browser_urls=browser_urls)

    if config.NBCONVERT:
        return

    global running_container
    running_container = container_name
    atexit.register(reap_running_container)

    if config.CONTAINER_PERSIST and config.CONTAINER_DETACH:
        message("exiting: container session will remain running.")
        running_container = None  # to avoid reaping
        sys.exit(0)
    else:
        if config.CONTAINER_PERSIST:
            prompt = "Type 'exit' to kill the container session, or 'D' to detach: "
        else:
            prompt = "Type 'exit' to kill the container session: "
        try:
            while True:
                a = INPUT(prompt)
                if a.lower() == 'exit':
                    sys.exit(0)
                if a.upper(
                ) == 'D' and config.CONTAINER_PERSIST and container_name:
                    running_container = None  # to avoid reaping
                    sys.exit(0)
        except BaseException as exc:
            if type(exc) is KeyboardInterrupt:
                message("Caught Ctrl+C")
                status = 1
            elif type(exc) is SystemExit:
                status = getattr(exc, 'code', 0)
                message("Exiting with status {}".format(status))
            else:
                message("Caught exception {} ({})".format(exc, type(exc)))
                status = 1
            # if not status:
            #     running_container = None  # to avoid reaping
            sys.exit(status)
コード例 #5
0
def check_recent_sessions(options, argv, parser=None):
    """
    Loads a recent session if requested

    :param options: Options object from ArgumentParser
    :param argv:    Argument list (from sys.argv[1:] initially)
    :param parser:  ArgumentParser object used to (re)parse the options

    :return: options, argv
                    Where options and argv may have been loaded from the recent
                    options file
    """
    make_radiopadre_dir()
    # load history
    try:
        readline.read_history_file(HISTORY_FILE)
    except IOError:
        pass

    resume_session = None
    # a single-digit argument resumes session #N
    if len(options.arguments) == 1 and re.match("^\d$", options.arguments[0]):
        resume_session = int(options.arguments[0])
    # no arguments is resume session #0
    elif not options.arguments:
        resume_session = 0

    if resume_session is not None:

        last = _load_recent_sessions()
        num_recent = len(last)
        if resume_session >= num_recent:
            bye(ff("no recent session #{resume_session}"))

        message("Your most recent radiopadre sessions are:")
        message("")
        for i, (_, opts) in enumerate(list(last.items())[::-1]):
            message("    [#{0}] {1}".format(i, opts), color="GREEN")
        message("")
        print(
            "\nInteractive startup mode. Edit arguments and press Enter to run, or Ctrl+C to bail out. "
        )
        print(
            "    (Ctrl+U + <NUM> + Enter will paste other recent session arguments from the list above)\n"
        )

        inp = None
        cmdline = ''
        readline.set_startup_hook(lambda: readline.insert_text(cmdline))

        while inp is None:
            # form up list of fake args to be re-parsed for the last session
            cmdline = list(last.items())[-(resume_session + 1)][1]
            # non-persisting options raised in command line shall be appended to the fake args
            for opt in config.NON_PERSISTING_OPTIONS:
                if opt.startswith("--") and getattr(options, opt[2:].replace(
                        "-", "_"), None):
                    cmdline += " " + opt
            cmdline += " "

            ## colors confuse Ctrl+U and such
            # prompt = ff("{logger.Colors.GREEN}[#{resume_session}]:{logger.Colors.ENDC} ")
            prompt = ff("[#{resume_session}] ")
            inp = INPUT(prompt)
            inp = inp.strip()
            if not inp:
                resume_session = 0
                inp = None
            elif re.match("^\d+$", inp):
                res = int(inp)
                if res >= num_recent:
                    warning(ff("no recent session #{res}"))
                else:
                    resume_session = res
                readline.remove_history_item(1)
                inp = None

        readline.set_startup_hook(None)

        global _last_input
        _last_input = inp

        argv = shlex.split(inp, posix=False)

        options = parser.parse_args(argv)

    return options, argv
コード例 #6
0
def start_session(container_name, selected_ports, userside_ports,
                  notebook_path, browser_urls):
    from iglesia import ABSROOTDIR, LOCAL_SESSION_DIR, SHADOW_SESSION_DIR
    radiopadre_dir = make_radiopadre_dir()
    docker_local = make_dir(radiopadre_dir + "/.docker-local")
    js9_tmp = make_dir(radiopadre_dir + "/.js9-tmp")
    session_info_dir = get_session_info_dir(container_name)

    # message(ff("Container name: {container_name}"))  # remote script will parse it

    os.environ["RADIOPADRE_CONTAINER_NAME"] = container_name
    os.environ["XDG_RUNTIME_DIR"] = ""
    docker_opts = ["--workdir", ABSROOTDIR]
    # setup mounts for work dir and home dir, if needed
    homedir = os.path.expanduser("~")
    docker_opts += [
        "-B",
        "{}:{}{}".format(ABSROOTDIR, ABSROOTDIR,
                         ""),  # ":ro" if orig_rootdir else ""),
        "-B",
        "{}:{}".format(radiopadre_dir, radiopadre_dir),
        # hides /home/user/.local, which if exposed, can confuse jupyter and ipython
        "-B",
        "{}:{}".format(docker_local,
                       os.path.realpath(os.path.join(homedir, ".local"))),
        # mount session info directory (needed to serve e.g. js9prefs.js)
        "-B",
        "{}:{}".format(session_info_dir, LOCAL_SESSION_DIR),
        "-B",
        "{}:{}".format(session_info_dir, SHADOW_SESSION_DIR),
        # mount a writeable tmp dir for the js9 install -- needed by js9helper
        "-B",
        "{}:/.radiopadre/venv/js9-www/tmp".format(js9_tmp),
    ]
    if config.CONTAINER_DEV:
        if os.path.isdir(config.CLIENT_INSTALL_PATH):
            docker_opts += [
                "-B",
                "{}:/radiopadre-client".format(config.CLIENT_INSTALL_PATH)
            ]
        if os.path.isdir(config.SERVER_INSTALL_PATH):
            docker_opts += [
                "-B", "{}:/radiopadre".format(config.SERVER_INSTALL_PATH)
            ]
    # if not config.CONTAINER_DEBUG:
    #     command = [singularity, "instance.start"] + docker_opts + \
    #               [singularity_image, container_name]
    #     message("running {}".format(" ".join(map(str, command))))
    #     subprocess.call(command)
    #     docker_opts = [singularity, "exec", "instance://{}".format(container_name)]
    # else:
    #     docker_opts = [singularity, "exec" ] + docker_opts + [singularity_image]
    docker_opts = [singularity, "run"] + docker_opts + [singularity_image]
    container_ports = selected_ports

    # build up command-line arguments
    docker_opts += _collect_runscript_arguments(container_ports +
                                                userside_ports)

    if notebook_path:
        docker_opts.append(notebook_path)

    _run_container(container_name,
                   docker_opts,
                   jupyter_port=selected_ports[0],
                   browser_urls=browser_urls,
                   singularity=True)

    if config.NBCONVERT:
        return

    try:
        while True:
            a = INPUT("Type 'exit' to kill the container session: ")
            if a.lower() == 'exit':
                sys.exit(0)
    except BaseException as exc:
        if type(exc) is KeyboardInterrupt:
            message("Caught Ctrl+C")
            status = 1
        elif type(exc) is SystemExit:
            status = getattr(exc, 'code', 0)
            message("Exiting with status {}".format(status))
        else:
            message("Caught exception {} ({})".format(exc, type(exc)))
            status = 1
        if status:
            message("Killing the container")
            subprocess.call([
                singularity, "instance.stop", singularity_image, container_name
            ],
                            stdout=DEVNULL)
        sys.exit(status)