Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

repository_ctx.download doesn't use netrc #13709

Open
dmivankov opened this issue Jul 19, 2021 · 6 comments
Open

repository_ctx.download doesn't use netrc #13709

dmivankov opened this issue Jul 19, 2021 · 6 comments
Labels
P2 We'll consider working on this in future. (Assignee optional) team-ExternalDeps External dependency handling, remote repositiories, WORKSPACE file. type: bug

Comments

@dmivankov
Copy link
Contributor

dmivankov commented Jul 19, 2021

Description of the problem / feature request:

It seems that repository_ctx.download(url) doesn't handle netrc auth (while http_archive/http_file can use it, also wget can fetch same url).

Rule in question is jvm_maven_import_external https://github.com/bazelbuild/bazel/blob/master/tools/build_defs/repo/jvm.bzl#L109

Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

Don't have repro yet, will try to add later

What operating system are you running Bazel on?

NixOS

What's the output of bazel info release?

release 4.1.0- (@non-git)

If bazel info release returns "development version" or "(@non-git)", tell us how you built Bazel.

nixpkgs

@dmivankov dmivankov changed the title repository_ctx.download doesn't use nettc repository_ctx.download doesn't use netrc Jul 19, 2021
@sventiffe sventiffe added team-OSS Issues for the Bazel OSS team: installation, release processBazel packaging, website untriaged labels Jul 21, 2021
@philwo philwo added team-ExternalDeps External dependency handling, remote repositiories, WORKSPACE file. type: bug P2 We'll consider working on this in future. (Assignee optional) and removed untriaged labels Aug 31, 2021
@philwo philwo removed the team-OSS Issues for the Bazel OSS team: installation, release processBazel packaging, website label Nov 29, 2021
@adam-azarchs
Copy link
Contributor

It doesn't out of the box, but it can be made to with a bit of boiler-plate:

load(
    "@bazel_tools//tools/build_defs/repo:utils.bzl",
    "read_netrc",
    "use_netrc",
)
load("@bazel_skylib//lib:versions.bzl", "versions")

def _use_netrc(netrc, urls, patterns):
    if versions.is_at_most("3.0.0", versions.get()):
        return use_netrc(netrc, urls)
    return use_netrc(netrc, urls, patterns)

def get_auth(ctx, urls):
    """Given the list of URLs obtain the correct auth dict.
    Args:
        ctx: The repository context.
        urls: A list of URLs.
    Returns:
        A dictionary of workspace attributes to update.
    """

    # Mostly copied from https://github.com/bazelbuild/bazel/blob/3.7.2/tools/build_defs/repo/http.bzl
    if ctx.attr.netrc:
        netrc = read_netrc(ctx, ctx.attr.netrc)
        return _use_netrc(netrc, urls, ctx.attr.auth_patterns)

    if not ctx.os.name.startswith("windows"):
        if "HOME" in ctx.os.environ:
            netrcfile = "%s/.netrc" % (ctx.os.environ["HOME"],)
            if ctx.execute(["test", "-f", netrcfile]).return_code == 0:
                netrc = read_netrc(ctx, netrcfile)
                return _use_netrc(netrc, urls, ctx.attr.auth_patterns)
    elif "USERPROFILE" in ctx.os.environ and ctx.os.name.startswith("windows"):
        netrcfile = "%s/.netrc" % (ctx.os.environ["USERPROFILE"])
        if ctx.path(netrcfile).exists:
            netrc = read_netrc(ctx, netrcfile)
            return _use_netrc(netrc, urls, ctx.attr.auth_patterns)
        netrcfile = "%s/_netrc" % (ctx.os.environ["USERPROFILE"])
        if ctx.path(netrcfile).exists:
            netrc = read_netrc(ctx, netrcfile)
            return _use_netrc(netrc, urls, ctx.attr.auth_patterns)

    return {}
    
def _my_rule_implementation(ctx):
    auth = get_auth(ctx, all_urls)

    download_info = ctx.download_and_extract(
        ctx.attr.urls,
        ctx.attr.sha256,
        auth = auth,
    )

That said it isn't ideal for every rule implementation to have to do this.

@pauldraper
Copy link
Contributor

pauldraper commented Dec 5, 2022

In recent versions, it's even simpler:

load("@bazel_tools//tools/build_defs/repo:utils.bzl", "read_netrc", "read_user_netrc", "use_netrc")

def _get_auth(ctx, urls):
    """Given the list of URLs obtain the correct auth dict."""
    if ctx.attr.netrc:
        netrc = read_netrc(ctx, ctx.attr.netrc)
    else:
        netrc = read_user_netrc(ctx)
    return use_netrc(netrc, urls, ctx.attr.auth_patterns)

def _my_rule_implementation(ctx):
    auth = _get_auth(ctx, all_urls)

    download_info = ctx.download_and_extract(
        ctx.attr.urls,
        ctx.attr.sha256,
        auth = auth,
    )

my_rule = rule(
  attrs = {
    "auth_patterns": attr.string_dict(),
    "netrc": attr.string(),
    "urls": attr.string_list(),
  },
  implementation = _my_rule_implementation,
)

@aryeh-looker
Copy link
Contributor

In recent versions, it's even simpler:

load("@bazel_tools//tools/build_defs/repo:utils.bzl", "read_netrc", "read_user_netrc", "use_netrc")

def _get_auth(ctx, urls):
    """Given the list of URLs obtain the correct auth dict."""
    if ctx.attr.netrc:
        netrc = read_netrc(ctx, ctx.attr.netrc)
    else:
        netrc = read_user_netrc(ctx)
    return use_netrc(netrc, urls, ctx.attr.auth_patterns)

def _my_rule_implementation(ctx):
    auth = _get_auth(ctx, all_urls)

    download_info = ctx.download_and_extract(
        ctx.attr.urls,
        ctx.attr.sha256,
        auth = auth,
    )

my_rule = rule(
  attrs = {
    "auth_patterns": attr.string_dict(),
    "netrc": attr.string(),
    "urls": attr.string_list(),
  },
  implementation = _my_rule_implementation,
)

I would have never found this in a billion years. Any link to documentation or your process on how you figured this out?

@adam-azarchs
Copy link
Contributor

Everything in @bazel_tools//, including the built-in http_archive, lives in https://github.com/bazelbuild/bazel/tree/6.1.2/tools/. You can just read the code there. Documentation would be nice, though.

@pauldraper
Copy link
Contributor

The always-comprehensive, always-accurate documentation: the Source.

:/

@Wyverald
Copy link
Member

Note for anyone blocked on this: using the NETRC environment variable or the --credential_helper flag should work around the issue, until we implement a proper fix. See integration test at

def testCredentialsFromNetrc(self):
for an example.

dmivankov added a commit to dmivankov/rules_scala that referenced this issue Aug 25, 2023
`auth=` parameter for `repository_ctx.download` is both
required to fetch from private registries and is not well-documented
bazelbuild/bazel#13709 (comment)

With this change
```python
rules_scala_toolchain_deps_repositories(
    maven_servers = ["some_private_artifactory_url"]
)
```
would be able to authenticate using default .netrc (like `~/.netrc`)
simuons pushed a commit to bazelbuild/rules_scala that referenced this issue Oct 2, 2023
`auth=` parameter for `repository_ctx.download` is both
required to fetch from private registries and is not well-documented
bazelbuild/bazel#13709 (comment)

With this change
```python
rules_scala_toolchain_deps_repositories(
    maven_servers = ["some_private_artifactory_url"]
)
```
would be able to authenticate using default .netrc (like `~/.netrc`)
copybara-service bot pushed a commit that referenced this issue Dec 7, 2023
Workaround for #13709

Closes #20417.

PiperOrigin-RevId: 588762567
Change-Id: Ie02d7ff6ffaad646bf67059bebc7e0d5894f079e
github-merge-queue bot pushed a commit that referenced this issue Jan 17, 2024
Workaround for #13709

Closes #20417.
Commit
ce8bd90

PiperOrigin-RevId: 588762567
Change-Id: Ie02d7ff6ffaad646bf67059bebc7e0d5894f079e

Co-authored-by: Gunnar Wagenknecht <gunnar@wagenknecht.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P2 We'll consider working on this in future. (Assignee optional) team-ExternalDeps External dependency handling, remote repositiories, WORKSPACE file. type: bug
Projects
None yet
Development

No branches or pull requests

7 participants