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

Oauth2 support without Python #626

Merged
merged 11 commits into from
Jul 17, 2024

Conversation

lukaszwawrzyk
Copy link
Contributor

Due to inactivity, I picked up this PR: #581

I implememented the mentioned workarounds, i.e. in case of windows, I try to run script using powershell, otherwise, I fallback to curl and then wget, both wrapped in a bash script.

I tested these with an azure repo which requires oauth2. I also tested it on windows. I found that the config.json is not found due to "stat" binary not existing on windows, so I fixed this too.

@lukaszwawrzyk lukaszwawrzyk mentioned this pull request Jun 12, 2024
oci/private/util.bzl Outdated Show resolved Hide resolved
oci/private/authn.bzl Outdated Show resolved Hide resolved
oci/private/authn.bzl Outdated Show resolved Hide resolved
oci/private/authn.bzl Outdated Show resolved Hide resolved
oci/private/authn.bzl Outdated Show resolved Hide resolved
oci/private/authn.bzl Outdated Show resolved Hide resolved
oci/private/authn.bzl Outdated Show resolved Hide resolved
@thesayyn
Copy link
Collaborator

Okay, this looks a bit better, this could use some tests similar to https://github.com/bazel-contrib/rules_oci/blob/2.x/e2e/assertion/oci_pull_auth_tests.bats

We will also need better error messages.

@Sowmya-Iyer
Copy link

While trying to oci.pull an azure container registry, I still get this error:

Error in download: java.io.IOException: Error downloading [<>] to /home/siyer/.cache/bazel/_bazel_siyer/c0c06e0bd45258079fb49c5a3cba7fd4/external/rules_oci~~oci~ard_x86_64_base/www-authenticate.json: GET returned 401 Unauthorized 

The PR #600 had actually fixed that issue for me though I didn't like the way it was done either

@thesayyn
Copy link
Collaborator

we should somehow incorporate that change here. identity tokens are not something we support at the moment, so we might as well it right at once and improve on it.

@lukaszwawrzyk
Copy link
Contributor Author

While trying to oci.pull an azure container registry, I still get this error:

Error in download: java.io.IOException: Error downloading [<>] to /home/siyer/.cache/bazel/_bazel_siyer/c0c06e0bd45258079fb49c5a3cba7fd4/external/rules_oci~~oci~ard_x86_64_base/www-authenticate.json: GET returned 401 Unauthorized 

The PR #600 had actually fixed that issue for me though I didn't like the way it was done either

If I az acr login --name <my repo> from terminal and then run bazel with changes in this PR it works. While it doesn't work without these changes at all.

@lukaszwawrzyk
Copy link
Contributor Author

Okay, this looks a bit better, this could use some tests similar to https://github.com/bazel-contrib/rules_oci/blob/2.x/e2e/assertion/oci_pull_auth_tests.bats

We will also need better error messages.

I think I fixed everything requested except for tests.

Current tests do not pass for me so it is hard to develop new, any suggestions?
I run them like this:

% pwd                                                                                                                                                             
/Users/lukasz/dev/rules/rules_oci/e2e/pull
% bazel test //:test_nobzlmod  

And this is the test log that I get:
test.log

@Sowmya-Iyer
Copy link

Sowmya-Iyer commented Jun 14, 2024

While trying to oci.pull an azure container registry, I still get this error:

Error in download: java.io.IOException: Error downloading [<>] to /home/siyer/.cache/bazel/_bazel_siyer/c0c06e0bd45258079fb49c5a3cba7fd4/external/rules_oci~~oci~ard_x86_64_base/www-authenticate.json: GET returned 401 Unauthorized 

The PR #600 had actually fixed that issue for me though I didn't like the way it was done either

If I az acr login --name <my repo> from terminal and then run bazel with changes in this PR it works. While it doesn't work without these changes at all.

  1. I added common --repo_env=OCI_ENABLE_OAUTH2_SUPPORT=1 to my bazelrc
  2. uodated Module.bzl with this commit as a git_override (4f78d52)
  3. az acr login --name <container_registry>

I ran the bazel with the above three changes

ERROR:

File "/home/siyer/.cache/bazel/_bazel_siyer/c0c06e0bd45258079fb49c5a3cba7fd4/external/rules_oci~/oci/private/authn.bzl", line 304, column 30, in _get_token
		rctx.download(
Error in download: java.io.IOException: Error downloading [<redacted>] to /home/siyer/.cache/bazel/_bazel_siyer/c0c06e0bd45258079fb49c5a3cba7fd4/external/rules_oci~~oci~<image_name>/www-authenticate.json: GET returned 401 Unauthorized

For my case, it doesn't seem to reach line 287, because I did not get the fail(IDENTITY_TOKEN_WARNING) without the bazelrc changes

@lukaszwawrzyk
Copy link
Contributor Author

lukaszwawrzyk commented Jun 14, 2024

I am not sure if the container registry that you are using is compatible with this fix or what is wrong in your case.

Firstly, I will post my reproduction if it can help on any way:

lukasz@vl-d-1274 test_rules_oci % bazel build @azur//:azur
Starting local Bazel server and connecting to it...
INFO: Repository azur instantiated at:
  /Users/lukasz/dev/rules/test_rules_oci/WORKSPACE:37:9: in <toplevel>
  /private/var/tmp/_bazel_lukasz/5b7ad260b35538c8633543ce918f5e2d/external/rules_oci/oci/pull.bzl:212:14: in oci_pull
Repository rule oci_alias defined at:
  /private/var/tmp/_bazel_lukasz/5b7ad260b35538c8633543ce918f5e2d/external/rules_oci/oci/private/pull.bzl:370:28: in <toplevel>
ERROR: An error occurred during the fetch of repository 'azur':
   Traceback (most recent call last):
	File "/private/var/tmp/_bazel_lukasz/5b7ad260b35538c8633543ce918f5e2d/external/rules_oci/oci/private/pull.bzl", line 304, column 55, in _oci_alias_impl
		manifest, _, digest = downloader.download_manifest(rctx.attr.identifier, "mf.json")
	File "/private/var/tmp/_bazel_lukasz/5b7ad260b35538c8633543ce918f5e2d/external/rules_oci/oci/private/pull.bzl", line 163, column 74, in lambda
		download_manifest = lambda identifier, output: _download_manifest(rctx, authn, identifier, output),
	File "/private/var/tmp/_bazel_lukasz/5b7ad260b35538c8633543ce918f5e2d/external/rules_oci/oci/private/pull.bzl", line 123, column 23, in _download_manifest
		result = _download(rctx, authn, identifier, output, "manifests", allow_fail = True)
	File "/private/var/tmp/_bazel_lukasz/5b7ad260b35538c8633543ce918f5e2d/external/rules_oci/oci/private/pull.bzl", line 89, column 27, in _download
		auth = authn.get_token(rctx.attr.registry, rctx.attr.repository)
	File "/private/var/tmp/_bazel_lukasz/5b7ad260b35538c8633543ce918f5e2d/external/rules_oci/oci/private/authn.bzl", line 356, column 49, in lambda
		get_token = lambda reg, repo: _get_token(rctx, state, reg, repo),
	File "/private/var/tmp/_bazel_lukasz/5b7ad260b35538c8633543ce918f5e2d/external/rules_oci/oci/private/authn.bzl", line 290, column 35, in _get_token
		response = _oauth2(
	File "/private/var/tmp/_bazel_lukasz/5b7ad260b35538c8633543ce918f5e2d/external/rules_oci/oci/private/authn.bzl", line 205, column 13, in _oauth2
		fail("oauth2 failed:\nSTDOUT:\n{}\nSTDERR:\n{}".format(result.stdout, result.stderr))
Error in fail: oauth2 failed:
STDOUT:

STDERR:
curl: (22) The requested URL returned error: 403
ERROR: oauth2 failed:
STDOUT:

STDERR:
curl: (22) The requested URL returned error: 403
INFO: Elapsed time: 7.087s
INFO: 0 processes.
ERROR: Build did NOT complete successfully
lukasz@vl-d-1274 test_rules_oci %
lukasz@vl-d-1274 test_rules_oci % az acr login --name dockerregistrytest99
Login Succeeded
lukasz@vl-d-1274 test_rules_oci % bazel build @azur//:azur
WARNING: Fetching from hello-world@v1 without an integrity hash. The result will not be cached.
WARNING: The registry sent a manifest with schemaVersion=1.
This commonly occurs when fetching from a registry that needs the Docker-Distribution-API-Version header to be set.

WARNING: The use of Curl fallback is deprecated and is set to be removed in version 2.0.
For more details, refer to: https://github.com/bazel-contrib/rules_oci/issues/456

WARNING: Fetching from hello-world@v1 without an integrity hash. The result will not be cached.
WARNING: Fetching from hello-world@v1 without an integrity hash. The result will not be cached.
WARNING: The registry sent a manifest with schemaVersion=1.
This commonly occurs when fetching from a registry that needs the Docker-Distribution-API-Version header to be set.

WARNING: The use of Curl fallback is deprecated and is set to be removed in version 2.0.
For more details, refer to: https://github.com/bazel-contrib/rules_oci/issues/456

WARNING: Fetching from hello-world@v1 without an integrity hash. The result will not be cached.
INFO: Analyzed target @@azur//:azur (87 packages loaded, 458 targets configured).
INFO: Found 1 target...
Target @@azur_single//:azur_single up-to-date:
  bazel-bin/external/azur_single/layout
INFO: Elapsed time: 6.932s, Critical Path: 0.02s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
lukasz@vl-d-1274 test_rules_oci % cat WORKSPACE
workspace(name = "my_workspace")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

local_repository(
    name = "rules_oci",
    path = "../rules_oci",
)

load("@rules_oci//oci:dependencies.bzl", "rules_oci_dependencies")

rules_oci_dependencies()

load("@rules_oci//oci:repositories.bzl", "LATEST_CRANE_VERSION", "oci_register_toolchains")

oci_register_toolchains(
    name = "oci",
    crane_version = LATEST_CRANE_VERSION,
    # Uncommenting the zot toolchain will cause it to be used instead of crane for some tasks.
    # Note that it does not support docker-format images.
    # zot_version = LATEST_ZOT_VERSION,
)

# You can pull your base images using oci_pull like this:
load("@rules_oci//oci:pull.bzl", "oci_pull")

oci_pull(
    name = "distroless_base",
    digest = "sha256:ccaef5ee2f1850270d453fdf700a5392534f8d1a8ca2acda391fbb6a06b81c86",
    image = "gcr.io/distroless/base",
    platforms = [
        "linux/amd64",
        "linux/arm64",
    ],
)

oci_pull(
  name = "azur",
  image = "dockerregistrytest99.azurecr.io/hello-world",
  tag = "v1",
  reproducible = False,
)%
lukasz@vl-d-1274 test_rules_oci % cat .bazelrc
common --repo_env=OCI_ENABLE_OAUTH2_SUPPORT=1%
lukasz@vl-d-1274 test_rules_oci % cd ../rules_oci
lukasz@vl-d-1274 rules_oci % git rev-parse HEAD
4f78d52446b074a377d7e12a1baf7ac8072a7343

First I get 403, my azure subscription was actually disabled, then I enabled it and logged in successfully, then I can download the image. In the error stack trace you can also see that it enters the new code. You can see details of my setup with further commands.

For you, new code is not used at all as you mentioned. The condition if pattern["login"] == "<token>" must be false for you.

For me, it goes to line 234, i.e. calls _fetch_auth_via_creds_helper based on my empty dict:

$ cat ~/.docker/config.json
{
	"auths": {
		"dockerregistrytest99.azurecr.io": {},
		"ghcr.io": {},
	},
	"credsStore": "desktop",
	"currentContext": "desktop-linux"
}

and then calls

$ docker-credential-desktop get <<< dockerregistrytest99.azurecr.io
{"ServerURL":"dockerregistrytest99.azurecr.io","Username":"\u003ctoken\u003e","Secret":"<redacted>"}

and based on Username key, login becomes <token> and the condition is true. We verified it on 2 different azure accounts (prod and the dummy test one that I created and use here) by 3 people on different macbooks.

I am curious why it works differently for you, you might want to trace how credentials are obtained for you and compare with what I have written here.

@Sowmya-Iyer
Copy link

Sowmya-Iyer commented Jun 14, 2024

So, I think the problem is in parsing the ~/.docker/config.json:

siyer@siyer-ThinkPad-T15g-Gen-2i:~/workspace/container/BuildFarm$ cat ~/.docker/config.json
{
	"auths": {
		"<registry>.azurecr.io": {
			"auth": "MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwOg==",
			"identitytoken": "<redacted>"
		}
	}
}

Line 240 looks for what follows ":" as password but as per this config it is ["identity_token"] . Since here auth is weirdly ending with ":" 00000000-0000-0000-0000-000000000000: , the "if not sep" condition fails and there is no error message and password is empty as well

oci/private/authn.bzl Outdated Show resolved Hide resolved
@lukaszwawrzyk
Copy link
Contributor Author

So, I think the problem is in parsing the ~/.docker/config.json:

siyer@siyer-ThinkPad-T15g-Gen-2i:~/workspace/container/BuildFarm$ cat ~/.docker/config.json
{
	"auths": {
		"<registry>.azurecr.io": {
			"auth": "MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwOg==",
			"identitytoken": "<redacted>"
		}
	}
}

Line 240 looks for what follows ":" as password but as per this config it is ["identity_token"] . Since here auth is weirdly ending with ":" 00000000-0000-0000-0000-000000000000: , the "if not sep" condition fails and there is no error message and password is empty as well

My best bet is that you are using linux, I managed to reproduce the issue on ubuntu. So the fix in the current PR works for Mac OS, but not for linux.

@lukaszwawrzyk
Copy link
Contributor Author

I integrated fix from @ddeville to this PR, I believe we now have a complete support of azure across operating systems. And for oauth2 hopefully in all cases.

Copy link
Collaborator

@thesayyn thesayyn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fantastic now. Only we knew how to add some tests for this.

@thesayyn
Copy link
Collaborator

I am going to hold this for a little bit so we can figure out some testing infra for this. i'll circle back to this next week.

@thesayyn
Copy link
Collaborator

thesayyn commented Jul 8, 2024

Hmm, there are some failures. Can you handle those?

@lukaszwawrzyk
Copy link
Contributor Author

@thesayyn it was a simple check missing, now it's all good

@wingsofovnia
Copy link

Great work! Looking forward to having it in the next releases.
Any chance @thesayyn we can get this merged for 1.8.1?

@thesayyn thesayyn merged commit 9948ee1 into bazel-contrib:main Jul 17, 2024
20 checks passed
@wingsofovnia
Copy link

Thank you. @thesayyn will this also get pulled to 2.x?

thesayyn pushed a commit that referenced this pull request Jul 25, 2024
@mpatou-openai
Copy link

I'm still seeing issues with azure actually. It might work if the login is <token> but I have 00000000-0000-0000-0000-000000000000 as login.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants