|
#!/bin/bash |
|
|
|
set -euo pipefail |
|
IFS=$'\n\t' |
|
|
|
NAMESPACE=`oc project -q` |
|
|
|
if [[ "$#" -gt 0 ]]; then |
|
NAMESPACE="$1" |
|
fi |
|
|
|
oc project "${NAMESPACE}" |
|
|
|
function get_istags() { |
|
tmpl=$'{{range $isindex, $is := .items}}' |
|
tmpl+=$'{{range $tag, $value := $is.status.tags}}' |
|
tmpl+=$'{{if and ($value.items) (not $value.conditions)}}' |
|
tmpl+=$'{{range $index, $item := $value.items}}' |
|
tmpl+=$'{{$is.metadata.namespace}}/{{$is.metadata.name}}' |
|
tmpl+=$':{{$value.tag}}#{{$index}}#{{.image}}#{{.dockerImageReference}}\n{{end}}' |
|
tmpl+=$'{{end}}{{end}}{{end}}' |
|
oc get is --all-namespaces -o "go-template=${tmpl}" |
|
} |
|
|
|
tmpdir="$(mktemp -d)" |
|
function cleanup() { |
|
rm -rf "${tmpdir}" |
|
} |
|
trap cleanup EXIT |
|
|
|
oc get --all-namespaces -o json rc >"${tmpdir}/rcs.json" |
|
oc get --all-namespaces -o json pod >"${tmpdir}/pods.json" |
|
oc get --all-namespaces -o json dc >"${tmpdir}/dcs.json" |
|
oc get --all-namespaces -o json bc >"${tmpdir}/bcs.json" |
|
|
|
function make_image_refs_jq_expr() { |
|
local image="$1" |
|
printf '%s' '.items | map(select(@json | contains(' |
|
printf '"%s"' "${image}" |
|
printf '))) | ' |
|
printf '%s | ' 'map(@text "\(.metadata.namespace)/\(.metadata.name)(app=\(.metadata.labels.app),created=\(.metadata.creationTimestamp))")' |
|
printf '%s\n' 'join("#")' |
|
} |
|
|
|
function count_arr_items() { |
|
echo "$1" | tr '#' '\n' | grep -v '^\s*$' | wc -l ||: |
|
} |
|
|
|
function print_references() { |
|
local podrefs="$1" |
|
local dcrefs="$2" |
|
local rcrefs="$3" |
|
local bcrefs="$4" |
|
local titles=( "pod" "dc" "rc" "bc" ) |
|
local index=0 |
|
for refs in "${podrefs:-}" "${dcrefs:-}" "${rcrefs:-}" "${bcrefs:-}"; do |
|
echo "${refs}" | tr '#' '\n' | while read -r ref; do |
|
if [[ "${ref}" =~ (.+),created=([^\)]*) ]]; then |
|
printf " ref'd by %s %s\t-\t-\t%s\t-\t-\n" "${titles[$index]}" "${BASH_REMATCH[1]})" "${BASH_REMATCH[2]}" ||: |
|
fi |
|
done |
|
index="$((${index} + 1))" |
|
done |
|
} |
|
|
|
function sort_images() { |
|
declare -A imagetags |
|
declare -A imagecreated |
|
declare -A imagerefs |
|
declare -A imagesizes |
|
declare -A refcounts |
|
declare -A podrefs |
|
declare -A dcrefs |
|
declare -A rcrefs |
|
declare -A bcrefs |
|
while read -r -u 3 ist; do |
|
IFS='#' read -r istag index image ref <<<"${ist}" |
|
if [[ "${istag}" == "END_OF_INPUT" ]]; then |
|
{ |
|
printf "ImageName\tRefCount\tSize\tCreated\tISTags\tDockerImageReference\n" |
|
while read -u 4 -r line; do |
|
img="$(echo "${line}" | cut -f 1)" |
|
echo "${line}" |
|
print_references "${podrefs[$img]:-}" "${dcrefs[$img]:-}" "${rcrefs[$img]:-}" "${bcrefs[$img]:-}" |
|
done 4< <(for img in "${!imagetags[@]}"; do |
|
tags="${imagetags[$img]##,}" |
|
if ! [[ "${tags}" =~ (^|,)${NAMESPACE}/ ]]; then |
|
continue |
|
fi |
|
size="${imagesizes[$img]}" |
|
created="${imagecreated[$img]}" |
|
refs="${imagerefs[$img]##,}" |
|
refcount="${refcounts[$img]}" |
|
printf '%s\t%s' "${img}" "${refcount}" |
|
printf '\t%s\t%s\t%s\t%s\n' "${size}" "${created}" "${tags}" "${refs}" |
|
done | sort -rnk 2) |
|
} | column -t -s $'\t' |
|
break |
|
fi |
|
|
|
tags="${imagetags[$image]:-}" |
|
if ! echo "${tags:-}" | grep -qF ",${istag}"; then |
|
imagetags[$image]="${tags},${istag}[${index}]" |
|
refcounts[$image]="$((${refcounts[$image]:-0} + 1))" |
|
fi |
|
|
|
refs="${imagerefs[$image]:-}" |
|
if [[ "${ref}" =~ ^([^@]+)(@[^@/]+|:[^/:]+)$ ]]; then |
|
ref="${BASH_REMATCH[1]}" |
|
fi |
|
if ! echo "${refs:-}" | grep -qF ",${ref}"; then |
|
imagerefs[$image]="${refs},${ref}" |
|
fi |
|
|
|
if [[ -z "${imagesizes[$image]:-}" ]]; then |
|
IFS='%' read -r size created <<<"$(oc get image -o json "${image}" | \ |
|
jq -r '@text "\(.dockerImageMetadata.Size | tostring)%\(.dockerImageMetadata.Created)"')" |
|
[[ "${size}" == 'null' ]] && size=0 |
|
imagesizes[$image]="${size}" |
|
imagecreated[$image]="${created}" |
|
refcount="${refcounts[$image]:-0}" |
|
jq_expr="$(make_image_refs_jq_expr "${image}")" |
|
podrefs[$image]="$(cat "${tmpdir}/pods.json" | jq -r "${jq_expr}")" |
|
dcrefs[$image]="$(cat "${tmpdir}/dcs.json" | jq -r "${jq_expr}")" |
|
rcrefs[$image]="$(cat "${tmpdir}/rcs.json" | jq -r "${jq_expr}")" |
|
bcrefs[$image]="$(cat "${tmpdir}/bcs.json" | jq -r "${jq_expr}")" |
|
for refs in "${podrefs[$image]}" "${dcrefs[$image]}" "${rcrefs[$image]}" "${bcrefs[$image]}"; do |
|
cnt="$(count_arr_items "${refs}")" |
|
refcount="$((${refcount} + ${cnt}))" |
|
done |
|
fi |
|
done 3< <(cat <(get_istags) <(echo "END_OF_INPUT#-#-")) |
|
} |
|
|
|
sort_images |
|
|