예제 #1
0
def test_validate_pip_config(mock_vnc, mock_gwc, missing_configs):
    configs = {"cachito_nexus_pypi_proxy_url": "foo", "cachito_nexus_pip_raw_repo_name": "bar"}
    for conf in missing_configs:
        configs.pop(conf)

    mock_gwc.return_value = configs
    if missing_configs:
        expected = f'The configuration "{missing_configs[0]}" must be set for this package manager'
        with pytest.raises(ConfigError, match=expected):
            validate_pip_config()
    else:
        validate_pip_config()
예제 #2
0
def fetch_pip_source(request_id, package_configs=None):
    """
    Resolve and fetch pip dependencies for a given request.

    :param int request_id: the Cachito request ID this is for
    :param list package_configs: the list of optional package configurations submitted by the user
    """
    version_output = run_cmd(["pip", "--version"], {})
    log.info(f"pip version: {version_output.strip()}")

    validate_pip_config()
    bundle_dir: RequestBundleDir = RequestBundleDir(request_id)

    log.info("Configuring Nexus for pip for the request %d", request_id)
    set_request_state(request_id, "in_progress", "Configuring Nexus for pip")
    pip_repo_name = get_pypi_hosted_repo_name(request_id)
    raw_repo_name = get_raw_hosted_repo_name(request_id)
    prepare_nexus_for_pip_request(pip_repo_name, raw_repo_name)

    log.info("Fetching dependencies for request %d", request_id)
    package_configs = package_configs or [{}]
    packages_data = []
    requirement_file_paths = []
    for pkg_cfg in package_configs:
        pkg_path = pkg_cfg.get("path", ".")
        source_dir = bundle_dir.app_subpath(pkg_path).source_dir
        set_request_state(
            request_id,
            "in_progress",
            f"Fetching dependencies at the {pkg_path!r} directory",
        )
        request = get_request(request_id)
        pkg_and_deps_info = resolve_pip(
            source_dir,
            request,
            requirement_files=pkg_cfg.get("requirements_files"),
            build_requirement_files=pkg_cfg.get("requirements_build_files"),
        )

        # defer custom requirement files creation to use the Nexus password in the URLs
        for requirement_file_path in pkg_and_deps_info.pop("requirements"):
            requirement_file_paths.append(requirement_file_path)

        # defer DB operations to use the Nexus password in the env vars
        packages_data.append(pkg_and_deps_info)

    log.info("Finalizing the Nexus configuration for pip for the request %d",
             request_id)
    set_request_state(request_id, "in_progress",
                      "Finalizing the Nexus configuration for pip")
    username = get_hosted_repositories_username(request_id)
    password = finalize_nexus_for_pip_request(pip_repo_name, raw_repo_name,
                                              username)

    # Set environment variables and config files
    pip_config_files = []
    for requirement_file_path in requirement_file_paths:
        custom_requirement_file = _get_custom_requirement_config_file(
            requirement_file_path, bundle_dir.source_root_dir, raw_repo_name,
            username, password)
        if custom_requirement_file:
            pip_config_files.append(custom_requirement_file)

    raw_url = get_pypi_hosted_repo_url(request_id)
    pip_index_url = get_index_url(raw_url, username, password)
    env_vars = {"PIP_INDEX_URL": {"value": pip_index_url, "kind": "literal"}}
    ca_cert = nexus.get_ca_cert()
    if ca_cert:
        ca_cert_path = os.path.join("app", "package-index-ca.pem")
        env_vars["PIP_CERT"] = {"value": ca_cert_path, "kind": "path"}
        pip_config_files.append(make_base64_config_file(ca_cert, ca_cert_path))

    worker_config = get_worker_config()
    env_vars.update(
        worker_config.cachito_default_environment_variables.get("pip", {}))

    update_request_env_vars(request_id, env_vars)

    packages_json_data = PackagesData()
    for pkg_cfg, pkg_data in zip(package_configs, packages_data):
        pkg_subpath = os.path.normpath(pkg_cfg.get("path", "."))
        pkg_info = pkg_data["package"]
        pkg_deps = pkg_data["dependencies"]
        packages_json_data.add_package(pkg_info, pkg_subpath, pkg_deps)
    packages_json_data.write_to_file(bundle_dir.pip_packages_data)

    if pip_config_files:
        update_request_with_config_files(request_id, pip_config_files)