From 2c05bfe4f835425918b8c994ff01122badcf4a18 Mon Sep 17 00:00:00 2001 From: infogulch Date: Tue, 4 May 2021 21:28:35 -0500 Subject: [PATCH] Initial support for ls --- docker-artifact.sh | 95 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 21 deletions(-) diff --git a/docker-artifact.sh b/docker-artifact.sh index 4b1c114..6262c93 100755 --- a/docker-artifact.sh +++ b/docker-artifact.sh @@ -12,26 +12,26 @@ function docker_cli_plugin_metadata { } __usage=" -Usage: docker artifact [command] [options] - +Usage: docker artifact [command] [options] [args] + Commands: - - ls - List files available to download directly from an image - download - Download files directly from an image that has been labeled - label - Label an image - + + ls - List labeled files available to download directly from an image + download - Download labeled files directly from an image + label - Label files in an image + Command usage: - + docker artifact ls [options] image_name docker artifact download [options] image_name file... docker artifact label [options] image_name file... - + Options: -v - verbose output -q - quiet output - + Examples: - + docker artifact ls infogulch/artifact-test docker artifact download infogulch/artifact-test /app/othertestfile.txt docker artifact label infogulch/artifact-test /testfile.txt @@ -44,7 +44,7 @@ function main { ;; artifact) case "$2" in - ls) + ls|list) list "${@:3}" ;; label) @@ -61,15 +61,57 @@ function main { esac } -function _search_layer { - local idmap="$1" - local imagetar="$2" - local layertar="$3" - local search="$4" - # look up digest associated with layer path - local digest="$(jq --arg key "$layertar" -r '.[$key]' <<< "$idmap")" - # extract layer from image | list files in layer | add / prefix | search for file | append =$digest to each found file - tar -f "$imagetar" -x "$layertar" -O | tar -t | sed s_^_/_ | grep -wx "$search" | sed 's_.$_\0='"$digest"'_' +function list { + local list="$(list_json "$@" | jq -r 'keys | .[]' | sed 's_^_ _')" + echo " ** The following files are available to download from $1: " + echo "$list" +} + +function list_json { + local image="$1" + local regex='^([-_a-z\.]+)/([-_a-z]+)(:([-_a-z]+))?$' + if [[ $image =~ $regex ]] ; then + registry="${BASH_REMATCH[1]}" + image="${BASH_REMATCH[2]}" + tag="${BASH_REMATCH[4]:-latest}" + if ! [[ $registry =~ \. ]] ; then + image="$registry/$image" + registry="registry-1.docker.io" + fi + else + echo "Failed to parse image '$image'" + exit 1 + fi + local token="$(get_token "$registry" "$image")" + LOG "Querying manifest to extract labels for '$registry/$image:$tag" + local manifest="$(curl --silent \ + -H "Accept:application/vnd.docker.container.image.v1+json" \ + -H "Authorization: Bearer $token" \ + "https://$registry/v2/$image/manifests/$tag")" + local labels="$(jq -r '.history[].v1Compatibility' <<< "$manifest" | jq --slurp -r '[.[].config | select(.Labels != null) | .Labels] | add')" + jq <<< "$labels" +} + +function get_token { + local registry="$1" + local image="$2" + if [[ ! -z "$REGISTRY_TOKEN" ]] ; then + echo "$REGISTRY_TOKEN" + return + fi + LOG "Retrieving registry token for $registry/$image" + case "$registry" in + registry-1.docker.io) + curl --silent "https://auth.docker.io/token?scope=repository:$image:pull&service=registry.docker.io" \ + | jq -r .token + ;; + *.azurecr.io) + echo "$REGISTRY_TOKEN" + ;; + *.dkr.ecr.*.amazonaws.com) + aws ecr get-authorization-token | jq -r '.authorizationData[0].authorizationToken' + ;; + esac } function label { @@ -126,6 +168,17 @@ function label { echo " ** Run 'docker push $image' to push it to your container repository" } +function _search_layer { + local idmap="$1" + local imagetar="$2" + local layertar="$3" + local search="$4" + # look up digest associated with layer path + local digest="$(jq --arg key "$layertar" -r '.[$key]' <<< "$idmap")" + # extract layer from image | list files in layer | add / prefix | search for file | append =$digest to each found file + tar -f "$imagetar" -x "$layertar" -O | tar -t | sed s_^_/_ | grep -wx "$search" | sed 's_.$_\0='"$digest"'_' +} + function delete_files { LOG "Cleaning up temp files $@" rm "$@"