Skip to content
Snippets Groups Projects
mpsd-software.py 40.8 KiB
Newer Older
    root_dir : pathlib.Path
        A Path object pointing to the root directory of the installation.
        Expect a subfolder root/mpsd_release in which we search for the
        toolchains.

    Returns
    -------
    toolchain_map : dict
        A dictionary containing available microarchitectures as keys and
        a list of available package_sets as values for each microarchitecture.

        Note: only toolchains can be reported at the moment (i.e. package_sets
        such as global and global_generic are missing, even if installed).

    """
    msg = f"Showing status of release {mpsd_release} in {root_dir}"
    logging.info(msg)
    plog = logging.getLogger("print")
    release_base_dir = root_dir / mpsd_release
    microarch = get_native_microarchitecture()
    toolchain_dir = release_base_dir / microarch
    spack_dir = toolchain_dir / "spack"
    # if the mpsd_release does not exist:
    if not release_base_dir.exists():
        logging.debug(f"Directory {str(release_base_dir)} does not exist.")
        logging.error(f"MPSD release '{mpsd_release}' is not installed.")
        return None

    # if the mpds_release directory exists but the spack repository is not fully
    # cloned - indicates some kind of incomplete installation:
    if not spack_dir.exists():
        logging.debug(f"Looking for files in {spack_dir}")
        logging.error(
            f"MPSD release '{mpsd_release}' has not been completely installed."
    # find all folders for all microarch in the release directory
    # except for the blacklisted files
    black_listed_files = [
        config_vars["cmd_log_file"],
        "spack-environments",
        "logs",
        "mpsd-spack-cache",
    ]
    list_of_microarchs_candidates = os.listdir(release_base_dir)
    list_of_microarchs = [
        x for x in list_of_microarchs_candidates if x not in black_listed_files
    ]
    logging.debug(f"{list_of_microarchs=}")

    toolchain_map = {}
    for microarch in list_of_microarchs:
        # get a list of all the toolchains in the microarch
        possible_toolchains = (release_base_dir / microarch).glob(
            "lmod/Core/toolchains/*.lua"
        )
        # append toolchain which is the name of the file without the .lua extension
        toolchain_map[microarch] = [toolchain.stem for toolchain in possible_toolchains]

    logging.debug(f"{toolchain_map=}")

    # pretty print the toolchain map key as the heading
    # and the value as the list of toolchains
Hans Fangohr's avatar
Hans Fangohr committed
    plog.info(f"Installed toolchains ({mpsd_release}):\n")
    for microarch, toolchains in toolchain_map.items():
        plog.info(f"- {microarch}")
        for toolchain in toolchains:
Hans Fangohr's avatar
Hans Fangohr committed
            plog.info(f"    {toolchain}")
        plog.info(f"    [module use {str(release_base_dir / microarch / 'lmod/Core')}]")
        plog.info("")
    return toolchain_map
def main():
    """Execute main entry point."""
Hans Fangohr's avatar
Hans Fangohr committed
    parser = argparse.ArgumentParser(
        description=about_intro,
        epilog=about_epilog,
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
Hans Fangohr's avatar
Hans Fangohr committed
        "-l",
        dest="loglevel",
        choices=["warning", "info", "debug"],
        required=False,
        default="warning",
        help="Set the log level",
    )
Hans Fangohr's avatar
Hans Fangohr committed
    parser.add_argument("--version", action="version", version=__version__)
Ashwin Kumar Karnad's avatar
Ashwin Kumar Karnad committed
    subparsers = parser.add_subparsers(
        dest="action", title="actions", description="valid actions", required=True
    )
    subparsers.required = True
    list_of_cmds = [
        ("available", "What is available for installation?"),
        ("install", "Install a software environment"),
        # ("reinstall", "Reinstall a software environment"),
        # ("remove", "Remove a software environment or toolchains from an environment"),
        # ("start-new", "Start a new software environment version"),
        ("status", "Show status: what is installed?"),
        ("prepare", "Prepare installation of MPSD-release (dev only)"),
    ]
    for cmd, help_text in list_of_cmds:
        subp = subparsers.add_parser(cmd, help=help_text)

        if cmd == "start-new":
            subp.add_argument(
                "--from-release",
                dest="from_release",
                type=str,
                required=True,
                help="Release version to start from",
            )
            subp.add_argument(
                "--to-release",
                dest="to_release",
                type=str,
                required=True,
                help="Release version to create",
            )
Ashwin Kumar Karnad's avatar
Ashwin Kumar Karnad committed
            subp.add_argument(
                "release",
                type=str,
                help="Release version to prepare, install, reinstall or remove",
Ashwin Kumar Karnad's avatar
Ashwin Kumar Karnad committed
            )
            if cmd in ["install", "reinstall", "remove"]:
Ashwin Kumar Karnad's avatar
Ashwin Kumar Karnad committed
                # "install" command needs additional documentation
                    f"One or more toolchains to command {cmd}. "
                    "Use 'ALL' to refer to all available package sets."
                subp.add_argument(
                    "package_set",  # first option defines attribute
                    # name `args.package_set` in `args = parser_args()`
Ashwin Kumar Karnad's avatar
Ashwin Kumar Karnad committed
                    nargs="+",
                )
                subp.add_argument(
                    "--enable-build-cache",
                    action="store_true",
                        "Enable Spack build cache. Useful for reinstallation but "
                        "consumes time and disk space."
    # Carry out the action
    args = parser.parse_args()
    # target dir is the place where this script exists. the
    root_dir = Path(os.path.dirname(os.path.realpath(__file__)))
        get_installer_log_file_path(args.release, args.action, root_dir),
    # sanity check for common mistakes in command line arguments
    if args.release.endswith("/"):  # happens easily with autocompletion
        logging.error(
            f"You provided mpsd-release='{args.release}'. "
            "Did you mean '{args.release.rstrip('/')}'?"
        )
        sys.exit(1)

    # Check the command and run related function
    if args.action == "remove":
        remove_environment(args.release, args.package_set, root_dir)
    elif args.action == "start-new":
        start_new_environment(args.from_release, args.to_release, root_dir)
    elif args.action == "install":
Ashwin Kumar Karnad's avatar
Ashwin Kumar Karnad committed
        install_environment(
            args.release, args.package_set, root_dir, args.enable_build_cache
Ashwin Kumar Karnad's avatar
Ashwin Kumar Karnad committed
        )
    elif args.action == "status":
Hans Fangohr's avatar
Hans Fangohr committed
        _ = environment_status(args.release, root_dir)
    elif args.action == "prepare":
        prepare_environment(args.release, root_dir)
Hans Fangohr's avatar
Hans Fangohr committed
    elif args.action == "available":
        get_available_package_sets(args.release)
Hans Fangohr's avatar
Hans Fangohr committed
    else:
        message = (
            f"No known action found ({args.action=}). Should probably never happen."
        )
Hans Fangohr's avatar
Hans Fangohr committed
        logging.error(message)
        raise NotImplementedError(message)
if __name__ == "__main__":