Deependra Patel
Deependra Patel

Reputation: 178

How to download jar from artifact registry (GCP)?

I have a maven Artifact Registry and am able to add dependency in pom.xml and get the jar.

I have another usecase where I would like to only download the jar using CLI something which you can easily do with other external maven repos eg curl https://repo1.maven.org/maven2/org/apache/iceberg/iceberg-spark-runtime/0.7.0-incubating/iceberg-spark-runtime-0.7.0-incubating.jar --output temp.jar

I don't see any instructions about how to do this.

Upvotes: 5

Views: 7580

Answers (5)

WesternGun
WesternGun

Reputation: 12728

Basically you provide your identity token as Bearer token in Authorization header for curl and that's all.

Created several functions to do it, you just provide your lib name like in POM file or just as a path, then you are good to go.

lib-to-path() {
    # $1: lib name, like com.example.group.artifact:lib:jar:12345678, or com/example/group/artifact/lib/12345678
    echo $1 | sed 's/pom://g' | sed 's/jar://g' | sed 's/:jar//g' | sed 's/[:]/\//g' | sed -E 's/(\w*)\.(\w*)/\1\/\2/g'
}


fetch-lib-iap() {
    if [ -z $1 ]; then 
        echo "Please provide lib name, like com.example.group.artifact:lib:jar:12345678"
        return 1
    fi
    lib_path="$(lib-to-path $1)"
    path="/home/${USER}/.m2/repository/$lib_path"
    echo "Saving to location: $path"
    version="$(basename $path)"
    parent_dir="$(echo $path | sed "s/$version//g")"
    lib="$(basename $parent_dir)"
    cd "$parent_dir"
    mkdir "$version"
    cd "$version"
    echo "Parent dir: $parent_dir, lib: $lib, version: $version"
    url="https://nexus.example.com/repository/$lib_path"
    download-lib-jar-pom $url jar $lib $version
    download-lib-jar-pom $url pom $lib $version
}

download-lib-jar-pom() {
    # $1: url w/o extension, $2: extension, $3: lib, $4: version
    filename="$3-$4.$2"
    touch "$filename"
    echo "Downloading: $1/$filename"
    # -O: download to a file as the remote filename
    curl -s -k -O "$1/$filename" --connect-timeout 10 -H "Authorization: Bearer $(gauth-impersonate-nexus-token 2>/dev/null)"
    if [[ "$2" == "pom" ]] && (head -2 "$filename" | grep "DOCTYPE html"); then
        echo "ERROR POM file $1! Only found 404 page!"
        rm "$filename"
        return 1
    fi
    if [ "$(size $filename)" == 0 ] ; then
        echo "ERROR! $filename not found, download size 0!"
        rm "$filename"
        return 1
    fi
    cd -
}

gauth-impersonate-nexus-token() {
    gcloud auth print-identity-token --impersonate-service-account="[email protected]" --audiences="some-aud" --include-email
}

Upvotes: 0

Ruslan Lomov
Ruslan Lomov

Reputation: 1

Here is what work for me:

    1. gcloud auth login
    2. curl -H "Authorization: Bearer \"$(gcloud auth application-default print-access-token)\"" \
       -o my_deployment.jar \
       -L https://us-maven.pkg.dev/gcp_project/my_artifactory/my_code_project/1.17.0/my_deployment_version.jar

The link to the jar can be found while pushing to the artifact registry.

Upvotes: 0

Linh Vu
Linh Vu

Reputation: 970

Additional to @Nicolas Roux's answer:

artifactRegistryMavenSecret is basically an encode64 of the Service Account json key.

So instead of runnig gcloud artifacts print-settings gradle and curl -u _json_key_base64:{{ artifactRegistryMavenSecret }}, another way is you can directly use the token from gcloud auth print-access-token, then apply this token to cURL.

For example:

1. gcloud auth activate-service-account [email protected] \
        --key-file=/path/key.json --project=PROJECT_ID
2. curl --oauth2-bearer "$(gcloud auth print-access-token)" \
        -o app-{{ version }}.jar \
        -L https://{{ region }}-maven.pkg.dev/{{ projectId }}/{{ repository }}/path/of/artifact/module/{{ version }}/app-{{ version }}.jar

By that, if you're working with Google Auth Action (google-github-actions/auth@v0) in Github Actions Workflow, then you can easily run the curl command without needing to extract artifactRegistryMavenSecret.

Upvotes: 3

Nicolas Roux
Nicolas Roux

Reputation: 579

I needed this too. I have configured a service account following gcp guide

Then, I have executed the following command to get authbasic credz :

gcloud artifacts print-settings gradle \
    [--project=PROJECT] \
    [--repository=REPOSITORY] \
    [--location=LOCATION] \
    --json-key=KEY-FILE \
    [--version-policy=VERSION-POLICY] \
    [--allow-snapshot-overwrites]

In the output you have the artifactRegistryMavenSecret.

Finally you get your artifact with :

curl -L -u _json_key_base64:{{ artifactRegistryMavenSecret }} https://{{ region }}-maven.pkg.dev/{{ projectId }}/{{ repository }}/path/of/artifact/module/{{ version }}/app-{{ version }}.jar -o file.jar

Upvotes: 3

ErnestoC
ErnestoC

Reputation: 2904

It seems like this feature as mentioned does not exist yet for Artifact Registry based on this open feature request (this feature request has currently no ETA). However, you can try to implement a Cloud build automation not to only save your built artifact in Artifact Registry, but also to store them in Google Cloud Storage or other Storage repositories; so you can easily access the JARs (since Cloud Storage supports direct downloading).

In order to do this, you would need to integrate Cloud Build with Artifact Registry. The documentation page has instructions to use Maven projects with Cloud Build and Artifact Registry. In addition, you can configure Cloud Build to store built artifacts in Cloud Storage.

Both of these integrations are configured through a Cloud Build configuration file. In this file, the steps for building a project are defined, including integrations to other serverless services. This integration would involve defining a target Maven repository:

steps:
- name: gcr.io/cloud-builders/mvn
  args: ['deploy']

And a location to deploy the artifacts into Cloud Storage:

artifacts:
  objects:
    location: [STORAGE_LOCATION]
    paths: [[ARTIFACT_PATH],[ARTIFACT_PATH], ...]

Upvotes: 2

Related Questions