From 59b3f6a49baa2d9805e832f388a9d8704e7c650b Mon Sep 17 00:00:00 2001 From: Gerald Pinder Date: Wed, 21 Aug 2024 16:04:37 -0400 Subject: [PATCH] fix: Fix docker login for oauth logins --- .github/workflows/build-pr.yml | 71 ++++++++++++++++++++++++++++++++ process/drivers/cosign_driver.rs | 3 +- process/drivers/docker_driver.rs | 5 ++- utils/src/constants.rs | 2 + utils/src/credentials.rs | 62 +++++++++------------------- 5 files changed, 98 insertions(+), 45 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 98e0b8f8..6982b669 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -313,6 +313,77 @@ jobs: grep -q 'ARG IMAGE_REGISTRY=ghcr.io/blue-build' Containerfile || exit 1 bluebuild build --retry-push -S sigstore --push -vv recipes/recipe.yml recipes/recipe-39.yml + docker-build-oauth-login: + timeout-minutes: 60 + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + needs: + - build + if: needs.build.outputs.push == 'true' + + steps: + - name: Google Auth + id: auth + uses: "google-github-actions/auth@v2" + with: + token_format: "access_token" + service_account: ${{ secrets.SERVICE_ACCOUNT }} + project_id: bluebuild-oidc + create_credentials_file: false + workload_identity_provider: ${{ secrets.WORKLOAD_IDENTITY }} + + - name: Maximize build space + uses: ublue-os/remove-unwanted-software@v6 + + - uses: sigstore/cosign-installer@v3.3.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + install: true + + - uses: actions-rust-lang/setup-rust-toolchain@v1 + + - name: Docker Auth + id: docker-auth + uses: "docker/login-action@v3" + with: + username: "oauth2accesstoken" + password: "${{ steps.auth.outputs.access_token }}" + registry: us-east1-docker.pkg.dev + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} + + - name: Install bluebuild + run: | + cargo install --path . --debug --all-features + + - name: Expose GitHub Runtime + uses: crazy-max/ghaction-github-runtime@v3 + + - name: Run Build + env: + GH_PR_EVENT_NUMBER: ${{ github.event.number }} + COSIGN_PRIVATE_KEY: ${{ secrets.TEST_SIGNING_SECRET }} + BB_BUILDKIT_CACHE_GHA: true + run: | + cd integration-tests/test-repo + bluebuild template -vv | tee Containerfile + bluebuild build \ + --registry us-east1-docker.pkg.dev \ + --registry-namespace bluebuild-oidc/bluebuild \ + --retry-push \ + --push \ + -vv \ + recipes/recipe.yml recipes/recipe-39.yml + podman-build: timeout-minutes: 60 runs-on: ubuntu-latest diff --git a/process/drivers/cosign_driver.rs b/process/drivers/cosign_driver.rs index 70f22ef5..9a39821a 100644 --- a/process/drivers/cosign_driver.rs +++ b/process/drivers/cosign_driver.rs @@ -2,7 +2,7 @@ use std::{fmt::Debug, fs, io::Write, path::Path, process::Stdio}; use blue_build_utils::{ cmd, - constants::{COSIGN_PASSWORD, COSIGN_PUB_PATH, COSIGN_YES}, + constants::{COSIGN_PASSWORD, COSIGN_PUB_PATH, COSIGN_YES, DOCKER_CONTENT_TRUST}, credentials::Credentials, }; use log::{debug, trace}; @@ -92,6 +92,7 @@ impl SigningDriver for CosignDriver { username, "--password-stdin", registry, + DOCKER_CONTENT_TRUST => "false", stdin = Stdio::piped(), stdout = Stdio::piped(), stderr = Stdio::piped(), diff --git a/process/drivers/docker_driver.rs b/process/drivers/docker_driver.rs index f6433ad8..f3bf92a9 100644 --- a/process/drivers/docker_driver.rs +++ b/process/drivers/docker_driver.rs @@ -9,7 +9,9 @@ use std::{ use blue_build_utils::{ cmd, - constants::{BB_BUILDKIT_CACHE_GHA, CONTAINER_FILE, DOCKER_HOST, SKOPEO_IMAGE}, + constants::{ + BB_BUILDKIT_CACHE_GHA, CONTAINER_FILE, DOCKER_CONTENT_TRUST, DOCKER_HOST, SKOPEO_IMAGE, + }, credentials::Credentials, string_vec, }; @@ -191,6 +193,7 @@ impl BuildDriver for DockerDriver { username, "--password-stdin", registry, + DOCKER_CONTENT_TRUST => "false", stdin = Stdio::piped(), stdout = Stdio::piped(), stderr = Stdio::piped(), diff --git a/utils/src/constants.rs b/utils/src/constants.rs index 55d77641..f6613238 100644 --- a/utils/src/constants.rs +++ b/utils/src/constants.rs @@ -26,6 +26,8 @@ pub const BB_USERNAME: &str = "BB_USERNAME"; // Docker vars pub const DOCKER_HOST: &str = "DOCKER_HOST"; +pub const DOCKER_CONTENT_TRUST: &str = "DOCKER_CONTENT_TRUST"; +pub const OAUTH_TOKEN_USER: &str = "oauth2accesstoken"; // Cosign vars pub const COSIGN_PASSWORD: &str = "COSIGN_PASSWORD"; diff --git a/utils/src/credentials.rs b/utils/src/credentials.rs index b33ca2a5..b5ba9ed8 100644 --- a/utils/src/credentials.rs +++ b/utils/src/credentials.rs @@ -55,58 +55,34 @@ static ENV_CREDENTIALS: LazyLock> = LazyLock::new(|| { env::var(CI_REGISTRY).ok(), env::var(GITHUB_ACTIONS).ok(), ) { - (Some(registry), _, _) if !registry.is_empty() => registry, - (None, Some(ci_registry), None) if !ci_registry.is_empty() => ci_registry, - (None, None, Some(_)) => string!("ghcr.io"), + (Some(registry), _, _) | (_, Some(registry), _) if !registry.is_empty() => registry, + (_, _, Some(_)) => string!("ghcr.io"), _ => return None, }; trace!("Registry: {registry:?}"); - let docker_creds = docker_credential::get_credential(®istry).ok(); - let podman_creds = docker_credential::get_podman_credential(®istry).ok(); - - let username = match ( - username, - env::var(CI_REGISTRY_USER).ok(), - env::var(GITHUB_ACTOR).ok(), - &docker_creds, - &podman_creds, - ) { - (Some(username), _, _, _, _) if !username.is_empty() => username, - (_, _, _, Some(DockerCredential::UsernamePassword(username, _)), _) - | (_, _, _, _, Some(DockerCredential::UsernamePassword(username, _))) - if !username.is_empty() => - { - username.clone() - } - (None, Some(ci_registry_user), None, _, _) if !ci_registry_user.is_empty() => { - ci_registry_user - } - (None, None, Some(github_actor), _, _) if !github_actor.is_empty() => github_actor, - _ => return None, - }; - trace!("Username: {username:?}"); - - let password = match ( - password, - env::var(CI_REGISTRY_PASSWORD).ok(), - env::var(GITHUB_TOKEN).ok(), - &docker_creds, - &podman_creds, + let (username, password) = match ( + (username, password), + docker_credential::get_credential(®istry).ok(), + docker_credential::get_podman_credential(®istry).ok(), + ( + env::var(CI_REGISTRY_USER).ok(), + env::var(CI_REGISTRY_PASSWORD).ok(), + ), + (env::var(GITHUB_ACTOR).ok(), env::var(GITHUB_TOKEN).ok()), ) { - (Some(password), _, _, _, _) if !password.is_empty() => password, - (_, _, _, Some(DockerCredential::UsernamePassword(_, password)), _) - | (_, _, _, _, Some(DockerCredential::UsernamePassword(_, password))) - if !password.is_empty() => + ((Some(username), Some(password)), _, _, _, _) + | (_, Some(DockerCredential::UsernamePassword(username, password)), _, _, _) + | (_, _, Some(DockerCredential::UsernamePassword(username, password)), _, _) + | (_, _, _, (Some(username), Some(password)), _) + | (_, _, _, _, (Some(username), Some(password))) + if !username.is_empty() && !password.is_empty() => { - password.clone() - } - (None, Some(ci_registry_password), None, _, _) if !ci_registry_password.is_empty() => { - ci_registry_password + (username, password) } - (None, None, Some(registry_token), _, _) if !registry_token.is_empty() => registry_token, _ => return None, }; + trace!("Username: {username}"); Some( Credentials::builder()