variable
$ rtUrl='https://artifactory.sample.com/artifactory'
$ repoName='my-repo'
$ buildName='my - repo'
$ buildNumber=12345
$ curlOpt="-s -g --netrc-file ~/.marslo/.netrc"
list
list subfolders in 1st depth
[!TIP] references:
- File List
Usage: GET /api/storage/{repoKey}/{folder-path}?list[&deep=0/1][&depth=n][&listFolders=0/1][&mdTimestamps=0/1][&includeRootPath=0/1]
$ /usr/bin/curl ${curlOpt} \
-X GET "${rtUrl}/api/storage/${repoName}-local?list&deep=1&listFolders=1&depth=1" |
jq -r '.files[].uri | split("/")[1])'
lastModified
[!NOTE|label:API:]
GET /api/storage/{repoKey}/{item-path}?lastModified
$ command curl -fsSL -g ${RT_URL}/api/storage/${repo}/${path}?lastModified |
jq -r .uri
quick search
[!NOTE|label:API:]
GET /api/search/artifact?name=name[&repos=x[,y]]
# it will return all artifacts with the name `name` in the `repo/path`
$ command curl -fsSL -g "${RT_URL}/api/search/artifact?name=${name}&repos=${repo}/${path}" |
jq .results[].uri
pattern search
[!NOTE|label:API:]
GET /api/search/pattern?pattern=repo-key:this/is/a/*pattern*.war
$ command curl -fsSL -g "${RT_URL}/api/search/pattern?pattern=${repo}:${env.JOB_NAME}/*/*original*" |
jq -r .files[] |
sort
list docker image tags
[!NOTE|label:references:]
- List Docker Tags
GET /api/docker/{repo-key}/v2/{image name}/tags/list?n=<Number of consecutive tags>&last=<last tag position (numeric) from previous response>
# API: /api/docker/<repo-key>/v2/<path/to/name>/tags/list
# i.e.:
$ curl -fsSL -XGET https://artifactory.example.com/artifactory/api/docker/devops-docker/v2/devops/ubuntu/tags/list |
jq -r .tags
[
"1.1-bionic",
"1.1-bionic-dind",
"1.2-bionic",
"1.2-bionic-dind",
"1.4-bionic",
"1.4-bionic-dind",
...
]
list docker registry
[!NOTE|label:references:]
- List Docker Repositories
GET /api/docker/{repo-key}/v2/_catalog?n=<n from the request>&last=<last tag value from previous response>
$ curl -fsSL -XGET https://artifactory.example.com/artifactory/api/docker/devops-docker/v2/_catalog |
jq -r .repositories
[
"busybox",
"centos",
...
]
# or
$ curl -fsSL -XGET https://artifactory.example.com/artifactory/api/docker/devops-docker/v2/_catalog |
jq -r .repositories[]
devops/jenkins
devops/jnlp
devops/ubuntu
...
repo
check repo exists
$ /usr/bin/curl ${curlOpt} \
-X GET "${rtUrl}/api/repositories" |
jq .[].key |
grep "${repo}"
get all repos
[!NOTE]
api/repositories
$ curl -sSg \
-X GET \
https://artifactory.sample.com/artifactory/api/repositories |
jq -r '.[] | .type + " ~> " + .key'
LOCAL ~> local-repo
REMOTE ~> remote-repo
VIRTUAL ~> virtual-repo
...
get all local repos
$ curl -sSg \
-X GET \
https://artifactory.sample.com/artifactory/api/repositories |
jq -r '.[] | select(.type == "LOCAL") | .key'
get all virtual repos
$ curl -sSg \ -X GET \ https://artifactory.sample.com/artifactory/api/repositories | jq -r '.[] | select(.type == "VIRTUAL") | .key'
- get all virtual repos, and repo name starts with '
' $ curl -sSg \ -X GET https://artifactory.sample.com/artifactory/api/repositories | jq -r '.[] | select((.type == "VIRTUAL") and select(.key | startswith("<project>"))) | .key'
- get defaultDeployRepo for all virutal repos who named starts with '
' $ for i in $(curl -sSg \ -XGET https://artifactory.sample.com/artifactory/api/repositories | jq -r '.[] | select((.type == "VIRTUAL") and select(.key | startswith("<project>"))) | .key' ); do echo "${i} : " curl -sSg \ --netrc-file /home/marslo/.marslo/.netrc \ -XGET https://artifactory.sample.com/artifactory/api/repositories/${i} | jq .defaultDeploymentRepo echo ' ' done
- get all virtual repos, and repo name starts with '
get all remote repos
$ curl -sSg \ -X GET \ https://artifactory.sample.com/artifactory/api/repositories | jq -r '.[] | select(.type == "REMOTE") | .key'
get repo size
[!NOTE]
api/storageinfo
get storage summary
[!NOTE] including:
binariesSummary
fileStoreSummary
repositoriesSummaryList
$ curl -s \ -XGET \ https://${rtUrl}/artifactory/api/storageinfo | jq '[.binariesSummary, .fileStoreSummary][]' { "binariesCount": "10,959", "binariesSize": "167.36 GB", "artifactsSize": "349.80 GB", "optimization": "47.85%", "itemsCount": "30,700", "artifactsCount": "20,547" } { "storageType": "file-system", "storageDirectory": "/opt/jfrog/artifactory/data/filestore", "totalSpace": "25.34 TB", "usedSpace": "10.41 TB (41.09%)", "freeSpace": "14.93 TB (58.91%)" }
build info
list all build-info id
$ curl -s \
--netrc-file ~/.marslo/.netrc \
-X GET ${rtUrl}/api/build/${buildName} |
jq -r '.buildsNumbers[].uri | split("/")[1]' |
sort -Vr
list all timestamps in ${buildName}
$ curl -s \
--netrc-file ~/.marslo/.netrc \
-X GET ${rtUrl}/api/build/${buildName} \
| jq .buildsNumbers[].started
List specific build-info
$ curl -s \
--netrc-file ~/.marslo/.netrc \
-X GET ${rtUrl}/api/build/${buildName}/${buildNumber}
- get start timestampe
$ curl -s \ --netrc-file ~/.marslo/.netrc \ -X GET ${rtUrl}/api/build/${buildName}/${buildNumber} \ | jq .buildInfo.started "2020-09-30T02:38:32.264-0700"
filter "buildInfo.env.JOB_NAME"
in all builds
$ BUILD_NAME='my - job'
$ RT_URL='https://artifactory.sample.com/artifactory'
$ for i in $(curl -sg -X GET "${RT_URL}/api/build/${BUILD_NAME}" | jq -r '.[][]?.uri' ); do
echo "~~~> ${i}"
curl -sg -X GET "${RT_URL}/api/build/${BUILD_NAME}${i}" | jq --raw-output '.buildInfo.properties."buildInfo.env.JOB_NAME"'
echo ''
done
or
#!/usr/bin/env bash
BUILD_NAME='my - build'
CURL_OPT="-sg --netrc-file $HOME/.marslo/.netrc"
RT_URL='https://artifactory.sample.com/artifactory'
for bid in $(curl ${CURL_OPT} -X GET "${RT_URL}/api/build/${BUILD_NAME}" | jq -r '.[][]?.uri'); do
curl ${CURL_OPT} -X GET "${RT_URL}/api/build/${BUILD_NAME}${bid}" \
| jq -r '.buildInfo.properties | select(."buildInfo.env.JOB_NAME" | contains("marslo"))' \
| jq -r '[."buildInfo.env.JOB_NAME" , ."buildInfo.env.BUILD_URL"]'
done
filter
"buildInfo.env.JOB_NAME"
by keyword$ BUILD_ID='/297' $ curl -sg -X GET "${RT_URL}/api/build/${BUILD_NAME}${BUILD_ID}" \ | jq -r '.buildInfo.properties | select(."buildInfo.env.JOB_NAME" | contains("marslo"))' \ | jq -r '."buildInfo.env.JOB_NAME"' marslo/rc
filter both
"buildInfo.env.BUILD_URL"
and"buildInfo.env.JOB_NAME"
ifJOB_NAME
contains keyword$ curl -sg -X GET "${RT_URL}/api/build/${BUILD_NAME}${BUILD_ID}" \ | jq -r '.buildInfo.properties | select(."buildInfo.env.JOB_NAME" | contains("marslo"))' \ | jq -r '[."buildInfo.env.JOB_NAME" , ."buildInfo.env.BUILD_URL"]' [ "marslo/rc", "https://jenkins.sample.com/job/marslo/job/rc/297/" ]
cleanup
delete all in my-repo
4 weeks ago
find.aql
$ cat find.aql items.find({ "repo": "my-repo", "type" : "folder" , "depth" : "1", "created" : { "$before" : "4w" } })
delete artifacts and buildinfo
rtURL='https://artifactory.sample.com/artifactory' cibuild='my-jenkins-build' repo='my-repo' curlOpt= '-s -g --netrc-file ~/.marslo/.netrc' for _i in $(curl ${curlOpt} \ -X POST ${rtURL}/api/search/aql \ -T find.aql | jq --raw-output .results[].name \ ); do curl ${curlOpt} -X DELETE "${rtURL}/${repo}/${_i}" curl ${curlOpt} -X DELETE "${rtURL}/api/build/${cibuild}?buildNumbers=${_i}&artifacts=1" curl ${curlOpt} -X DELETE "${rtUrl}/api/trash/clean/${repo}/${_i}" curl ${curlOpt} -X DELETE "${rtUrl}/api/trash/clean/artifactory-build-info" done
trash can
empty trash can
$ curl -s \
-g \
--netrc-file ~/.marslo/.netrc' \
-X POST \
"${rtUrl}/api/trash/empty"
list items in trash can
$ curl -s \
-g \
--netrc-file ~/.marslo/.netrc' \
-X GET \
"${rtURL}/api/storage/auto-trashcan" | jq .children[].uri
builds rotation via api/build/retention
$ date -d 'now - 2 months' +%s%3N
1597232120161
$ date -d @$(echo '1597232120161' | rev | cut -c4- | rev)
Wed Aug 12 19:35:20 CST 2020
$ cat rotation.json
{
"deleteBuildArtifacts" : true ,
"count" : 3 ,
"minimumBuildDate" : 1597232120161 ,
"buildNumbersNotToBeDiscarded" : []
}
$ curl -s \
-g \
-X POST \
-d @rotation.json \
-H "Content-Type: application/json" \
--netrc-file ~/.marslo/.netrc' \
"https://artifactory.sample.com/artifactory/api/build/retention/build%20-%20name?async=false"
promote
reference:
$ cat promot.json
{
"status": "released",
"ciUser": "ci-user",
"dryRun" : false,
"targetRepo" : "my-repo-release",
"copy": true,
"artifacts" : true,
"dependencies" : true,
"scopes" : [ "compile", "runtime" ],
"properties": {
"release-name": ["marslo-test"]
}
}
$ curl -s \
-g \
-i \
-k \
-H "Content-type:application/json" \
-d @promot.json \
-X POST \
'${rtURL}/api/build/promote/${buildName}/<buildID>'
property
add property
$ path='libs-release-local/pkg'
$ properties=$('os=win,linux|qa=done' | sed 's:|:%7C:')
$ curl -s \
-g \
-I \
--netrc-file ~/.marslo/.netrc \
-X PUT \
'${rtURL}/storage/${repoName}-local/${path}?properties=${properties}&recursive=1'
get result
$ curl -sgI \ --netrc-file ~/.marslo/.netrc \ -X PUT \ '${rtURL}/storage/${repoName}-local/${path}?properties=${properties}&recursive=1' \ | sed -rn 's:^HTTP/2\s?([0-9]+)\s?:\1:gp' 204 # or 400 # or 404
search
via pattern search
$ pattern='*/pkg/*/*.jar'
$ curl -s \
-g \
-k \
--netrc-file ~/.marslo/.netrc \
-X GET \
"${rtURL}/search/pattern?pattern=${repoName}-local:${pattern}"
via aql search
$ curl -s \
-k \
-X POST \
-H 'Content-Type:text/plain' \
'https://artifactory.sample.com/artifactory/api/search/aql' \
-d 'builds.find({
"name": "my - build - dev",
"created": {"$before": "3days"}
}).sort({"$desc": ["created"]}).limit(1)
'
deploy
deploy single artifacts
$ curl -gsSL \
--netrc-file ~/.marslo/.netrc \
-XPUT \
"https://artifactory.sample.com/artifactory/<repo-name>/<path/to/file.txt>" \
-T <artifacts>.txt
deploy bundle artifact
$ curl -g \
-s \
-SL \
-H "X-Explode-Archive-Atomic: true" \
-X PUT \
"https://artifactory.sample.com/artifactory/<repo-name>/<path>/" \
-T <artifacts>.[zip\|tar.gz\|tgz] # ^
# `/` is mandatory
deploy docker image via API
[!NOTE|label:references:]
$ curl -X POST -H "X-JFrog-Art-Api:$ARTI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"targetRepo" : "stef-docker-local",
"dockerRepository" : "hello-world",
"targetDockerRepository" : "hello-world",
"tag" : "1.0.0",
"targetTag" : "prod",
"copy": false }' \
https://xxxx.jfrog.io/artifactory/api/docker/default-docker-local/v2/promote
Promotion ended successfully%
access
generate access token
[!NOTE|label:references:]
- ARTIFACTORY: Creating Access Tokens in Artifactory
- authenticating via
Identify Token
generate new
$ export token='cm************************************************************w4' # Identify Token # generate $ curl -H "Authorization: Bearer $token " \ -XPOST "https://artifactory.sample.com/access/api/v1/tokens" \ -d '{"description" : "YOUR-DESCRIPTION", "token_id" : "YOUR-TOKEN-ID", "scope" : "applied-permissions/admin", "token_type" : "access_token", "include_reference_token" : "true"}' \ -H "Content-type: application/json" { "token_id" : "cf25f93d-e0b2-43ca-8adc-8e75c49b16d2", "access_token" : "ey*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************Zw", "expires_in" : 31536000, "scope" : "applied-permissions/admin", "token_type" : "Bearer", "reference_token" : "cm************************************************************Zz", "description" : "YOUR-DESCRIPTION" }
list all
$ curl -XGET -H "Authorization: Bearer $token " \ https://artifactory.sample.com/access/api/v1/tokens # to filter $ curl -XGET -H "Authorization: Bearer $token " https://artifactory.sample.com/access/api/v1/tokens | jq -r '.tokens[] | select( .scope == "applied-permissions/admin" )'