Exemple #1
0
def do_download(args: argparse.Namespace) -> str:
    """
    Download tarball from remote models repository.

    :param args: the arguments passed on the command line
    :type args: :class:`argparse.Namespace` object
    :rtype: None
    """
    try:
        remote = RemoteModelIndex(org=args.org)
        req = requirements.Requirement(args.package)
        pack_name = req.name
        specifier = req.specifier
        all_versions = remote.list_package_vers(pack_name)
        if all_versions:
            compatible_version = list(specifier.filter(all_versions))
            if compatible_version:
                vers = compatible_version[0]
                _log.info(f"Downloading {pack_name} {vers}")
                arch_path = remote.download(pack_name, vers, dest=args.dest)
                _log.info(f"Successfully downloaded packaging {pack_name} in {arch_path}")
                return arch_path
            else:
                _log.error(f"No version that satisfy requirements '{specifier}' for '{pack_name}'.")
                _log.warning(f"Available versions: {','.join(all_versions)}")
    except MacsyDataLimitError as err:
        _log.critical(str(err))
Exemple #2
0
def build_runner_image(docker_client, config, name, release):
    requirement = requirements.Requirement(release)

    # Markers would not make much sense here and url are unsupported.
    assert requirement.marker is None, requirement
    assert requirement.url is None, requirement

    with op.docker_build_context('resources/docker/runner-image') as build_dir:
        context = {
            'base_image': naming.image_name(config, 'root'),
            'entrypoint_name': config['entrypoint_name'],
            'app_name': requirement.name,
            'app_extras': ','.join(sorted(requirement.extras)),
            'app_version': helpers.get_version_from_requirement(requirement),
            'volumes': config['volumes'],
            'ports': config['ports'],
        }

        helpers.render_template(
            os.path.join(build_dir, 'Dockerfile.j2'),
            os.path.join(build_dir, 'Dockerfile'),
            context,
        )

        if config.get('pip_constraint'):
            shutil.copyfile(
                config['pip_constraint'],
                os.path.join(build_dir, 'constraints.txt'),
            )

        with wheel_server(docker_client, config) as wheel_server_ip:
            build_env = {
                'GROCKER_WHEEL_SERVER_IP': wheel_server_ip,
            }
            return op.docker_build_image(
                docker_client,
                build_dir,
                name,
                role='runner',
                buildargs=build_env,
                nocache=True,
            )
Exemple #3
0
 def parse_from_req(cls, release):
     requirement = requirements.Requirement(release)
     if len(requirement.specifier) != 1:
         raise ValueError("A single exact specifier is mandatory: %s" %
                          requirement)
     if requirement.url or requirement.marker:
         raise ValueError(
             "Invalid requirement: %s: marker and url are ignored" %
             requirement)
     spec = list(requirement.specifier)[0]
     if spec.operator not in ('==', '==='):
         raise ValueError("Only exact specifier are accepted: %s" %
                          requirement)
     version = spec.version
     return cls(
         project_name=requirement.name,
         operator=spec.operator,
         version=version,
         extras=sorted(requirement.extras),
         filepath=None,
     )
Exemple #4
0
 def pep508(value: str) -> bool:
     try:
         _req.Requirement(value)
         return True
     except _req.InvalidRequirement:
         return False
Exemple #5
0
def do_install(args: argparse.Namespace) -> None:
    """
    Install new models in macsyfinder local models repository.

    :param args: the arguments passed on the command line
    :type args: :class:`argparse.Namespace` object
    :rtype: None
    """
    if os.path.exists(args.package):
        remote = False
        pack_name, inst_vers = parse_arch_path(args.package)
        user_req = requirements.Requirement(f"{pack_name}=={inst_vers}")
    else:
        remote = True
        user_req = requirements.Requirement(args.package)

    pack_name = user_req.name
    inst_pack_loc = _find_installed_package(pack_name)

    if inst_pack_loc:
        pack = Package(inst_pack_loc.path)
        try:
            local_vers = version.Version(pack.metadata['vers'])
        except FileNotFoundError:
            _log.error(f"{pack_name} locally installed is corrupted.")
            _log.warning(f"You can fix it by removing '{inst_pack_loc.path}'.")
            sys.tracebacklimit = 0
            raise RuntimeError() from None
    else:
        local_vers = None
    user_specifier = user_req.specifier
    if not user_specifier and inst_pack_loc:
        # the user do not request for a specific version
        # and there already a version installed locally
        user_specifier = specifiers.SpecifierSet(f">{local_vers}")

    if remote:
        try:
            all_available_versions = _get_remote_available_versions(pack_name, args.org)
        except (ValueError, MacsyDataLimitError) as err:
            _log.error(str(err))
            sys.tracebacklimit = 0
            raise ValueError from None
    else:
        all_available_versions = [inst_vers]

    compatible_version = list(user_specifier.filter(all_available_versions))
    if not compatible_version and local_vers:
        target_vers = version.Version(all_available_versions[0])
        if target_vers == local_vers and not args.force:
            _log.warning(f"Requirement already satisfied: {pack_name}{user_specifier} in {pack.path}.\n"
                         f"To force installation use option -f --force-reinstall.")
            return None
        elif target_vers < local_vers and not args.force:
            _log.warning(f"{pack_name} ({local_vers}) is already installed.\n"
                         f"To downgrade to {target_vers} use option -f --force-reinstall.")
            return None
        else:
            # target_vers == local_vers and args.force:
            # target_vers < local_vers and args.force:
            pass
    elif not compatible_version:
        # No compatible version and not local version
        _log.warning(f"Could not find version that satisfied '{pack_name}{user_specifier}'")
        return None
    else:
        # it exists at least one compatible version
        target_vers = version.Version(compatible_version[0])
        if inst_pack_loc:
            if target_vers > local_vers and not args.upgrade:
                _log.warning(f"{pack_name} ({local_vers}) is already installed but {target_vers} version is available.\n"
                             f"To install it please run 'macsydata install --upgrade {pack_name}'")
                return None
            elif target_vers == local_vers and not args.force:
                _log.warning(f"Requirement already satisfied: {pack_name}{user_specifier} in {pack.path}.\n"
                             f"To force installation use option -f --force-reinstall.")
                return None
            else:
                # target_vers > local_vers and args.upgrade:
                # I have to install a new package
                pass

    # if i'm here it's mean I have to install a new package
    if remote:
        _log.info(f"Downloading {pack_name} ({target_vers}).")
        model_index = RemoteModelIndex(org=args.org, cache=args.cache)
        _log.debug(f"call download with pack_name={pack_name}, vers={target_vers}")
        arch_path = model_index.download(pack_name, str(target_vers))
    else:
        model_index = LocalModelIndex(cache=args.cache)
        arch_path = args.package

    _log.info(f"Extracting {pack_name} ({target_vers}).")
    cached_pack = model_index.unarchive_package(arch_path)

    if args.user:
        dest = os.path.realpath(os.path.join(os.path.expanduser('~'), '.macsyfinder', 'data'))
        if os.path.exists(dest) and not os.path.isdir(dest):
            raise RuntimeError("'{}' already exist and is not a directory.")
        elif not os.path.exists(dest):
            os.makedirs(dest)
    else:
        defaults = MacsyDefaults()
        config = Config(defaults, argparse.Namespace())
        dest = config.models_dir()
    if inst_pack_loc:
        old_pack_path = f"{inst_pack_loc.path}.old"
        shutil.move(inst_pack_loc.path, old_pack_path)

    _log.info(f"Installing {pack_name} ({target_vers}) in {dest}")
    try:
        shutil.move(cached_pack, dest)
    except PermissionError as err:
        _log.error(f"{dest} is not writable: {err}")
        _log.warning(f"Maybe you can use --user option to install in your HOME.")
        sys.tracebacklimit = 0
        raise ValueError() from None

    _log.info("Cleaning.")
    shutil.rmtree(pathlib.Path(cached_pack).parent)
    if inst_pack_loc:
        shutil.rmtree(old_pack_path)
    _log.info(f"The models {pack_name} ({target_vers}) have been installed successfully.")