Golden Codes - armanexplorer planet

Practical code snippets for Django, Python, Bash, Git and All!

View on GitHub
#!/bin/bash
set -eo pipefail

# check `jq` is installed
if ! [ -x "$(command -v jq)" ]; then
    apt update
    apt install jq
fi

# default FQDN registry name
DEF_FULL_REG="https://registry.example.com"

# colors
INFO='\e[34m'
ERROR='\e[31m'
RESET='\e[0m'

CMD=$0

function isTruthy {
    local arg=$1

    if [[ "$arg" = true ]] || [[ "$arg" = "true" ]] || [[ "$arg" -eq 1 ]]; then
        echo "true"
    fi

}

if [[ ${TRACE} ]] && [[ $(isTruthy "$TRACE") ]]; then
    set -x
fi

function usage {
    cat <<EOU

    Usage:

    $CMD REGISTRY_BASE_URL ACTION [OPTIONS..]

    Actions:

    - list               list repos

    - list REPO          list tags for repo

    - delete REPO TAG    delete tag for repo

    Example:

    List all repos
        /$ $CMD https://registry.my.domain list

    List tags for one repo
        /$ $CMD https://registry.my.domain list some-repo

    Delete tag for a repo
        /$ $CMD https://registry.my.domain delete some-repo some-tag


EOU
    exit 1
}

[ $# -lt 1 ] && usage

set +e

# check if the command includes registry FQDN as the first param
if [[ $1 == http* ]]; then
    FULL_REG=$1
    shift
else
    FULL_REG=$DEF_FULL_REG
fi

[ -z "$FULL_REG" ] && echo >&2 -e "${ERROR}ERROR: You must provide registry url as arg or default (No one is present)${RESET}" && usage

# inform user about the registry being used
echo -e "(${INFO}Registry: ${FULL_REG}${RESET})"
echo

PROTO="$(echo $FULL_REG | grep :// | sed -e's,^\(.*://\).*,\1,g')"

set -e

[ -z "$PROTO" ] && echo >&2 -e "${ERROR}ERROR: Must have protocol in registry url${RESET}" && usage

# remove the protocol
REG=${FULL_REG/$PROTO/}

ACTION="$1"
shift

CREDS=""
DOCKER_CONFIG="$HOME/.docker/config.json"

if [[ ${BASIC_AUTH} ]]; then
    CREDS="Authorization: Basic $(echo -n $BASIC_AUTH | base64)"
elif [[ -f "$DOCKER_CONFIG" ]]; then
    AUTH_INFO=$(jq -r '.auths["'$REG'"].auth' <"$DOCKER_CONFIG")
    if [ "$AUTH_INFO" = "null" ]; then
        AUTH_INFO=$(jq -r '.auths."'$PROTO$REG'".auth' <"$DOCKER_CONFIG")
        if [ "$AUTH_INFO" = "null" ]; then
            echo -e "${ERROR}ERROR: Failed to retrieve credentials from $DOCKER_CONFIG for ${REG}!${RESET}"
            exit 4
        fi
    fi
    CREDS="Authorization: Basic $AUTH_INFO"
fi

SEC_FLAG=""

if [[ ${INSECURE_REGISTRY} ]] && [[ $(isTruthy "$INSECURE_REGISTRY") ]]; then
    SEC_FLAG="-k"
fi

function curlCmd {
    curl "$SEC_FLAG" --header "$CREDS" $*
}

case "$ACTION" in
list)
    if [ $# -eq 1 ]; then
        repo=${1}
        if [ -n "$repo" ]; then
            curlCmd -s "$PROTO$REG/v2/$repo/tags/list" | jq -r '.tags|.[]'
        fi
    else
        curlCmd -s "$PROTO$REG/v2/_catalog?n=500" | jq -r '.repositories|.[]'
    fi

    ;;
delete)
    repo=$1
    tag=$2
    response=$(curlCmd -v -s -H "Accept:application/vnd.docker.distribution.manifest.v2+json" "$PROTO$REG/v2/$repo/manifests/$tag" 2>&1)
    digest=$(echo "$response" | grep -i "< Docker-Content-Digest:" | awk '{print $3}' || echo "")
    [ -z "$digest" ] &&
        response=$(curlCmd -v -s -H "Accept:application/vnd.oci.image.manifest.v1+json" "$PROTO$REG/v2/$repo/manifests/$tag" 2>&1) &&
        digest=$(echo "$response" | grep -i "< Docker-Content-Digest:" | awk '{print $3}')
    digest=${digest//[$'\t\r\n']/}
    echo "DIGEST: $digest"
    result=$(curlCmd -s -o /dev/null -w "%{http_code}" -H "Accept:application/vnd.docker.distribution.manifest.v2+json" -X DELETE "$PROTO$REG/v2/$repo/manifests/$digest")
    if [ "$result" -eq 202 ]; then
        echo "Successfully deleted"
        exit 0
    else
        echo "Failed to delete: $result"
        exit 3
    fi
    ;;
esac