اجرای اسکریپت چک کردن ایمیج های قابل حذف

ابتدا فایل های مورد نیاز را ایجاد میکنیم:

mkdir -p /opt/registry-retention

cat > /opt/registry-retention/registry-retention.conf <<'EOF'
# Registry API protocol
REGISTRY_SCHEME="http"

# Registry address
REGISTRY_ADDRESS="10.10.10.99:5000"

# Local Docker Registry container name
REGISTRY_CONTAINER="registry"

# Repository storage path INSIDE the Registry container
REGISTRY_REPOSITORIES_PATH="/var/lib/registry/docker/registry/v2/repositories"

# Keep the latest N unique image digests per repository
KEEP_LAST=2

# Detailed dry-run report
REPORT_FILE="/opt/registry-retention/registry-retention-report.tsv"

# Optional Registry Basic Authentication
# Leave empty if authentication is not enabled
REGISTRY_USERNAME=""
REGISTRY_PASSWORD=""

# Used by Registry garbage collection
REGISTRY_IMAGE="registry:latest"

# Registry storage source mounted at /var/lib/registry
# For a named Docker volume:
REGISTRY_STORAGE_SOURCE="rke-registry"

# Registry config file on the HOST
REGISTRY_CONFIG_HOST="/etc/docker/registry/config.yml"
EOF

chmod 600 /opt/registry-retention/registry-retention.conf

این موارد را بر اساس اطلاعات رجیستری خود تغییر میدهیم.

برای گرفتن گزارش کامل ایمیج های قابل حذف در رجیستری ابتدا اسکریپت زیر را اجرا میکنیم:

cat > /opt/registry-retention/registry-retention-dry-run.sh <<'EOF'
#!/usr/bin/env bash

set -euo pipefail

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="${CONFIG_FILE:-${SCRIPT_DIR}/registry-retention.conf}"

# -------------------------------------------------------------------
# Load and validate configuration
# -------------------------------------------------------------------

if [[ ! -f "$CONFIG_FILE" ]]; then
    echo "ERROR: Configuration file not found: $CONFIG_FILE" >&2
    exit 1
fi

# shellcheck source=/dev/null
source "$CONFIG_FILE"

required_commands=(
    curl
    jq
    docker
    sort
    awk
    mktemp
    head
    tail
    wc
)

for command_name in "${required_commands[@]}"; do
    if ! command -v "$command_name" >/dev/null 2>&1; then
        echo "ERROR: Required command not found: $command_name" >&2
        exit 1
    fi
done

required_variables=(
    REGISTRY_SCHEME
    REGISTRY_ADDRESS
    REGISTRY_CONTAINER
    REGISTRY_REPOSITORIES_PATH
    KEEP_LAST
    REPORT_FILE
)

for variable_name in "${required_variables[@]}"; do
    if [[ -z "${!variable_name:-}" ]]; then
        echo "ERROR: Required configuration is empty: $variable_name" >&2
        exit 1
    fi
done

if ! [[ "$KEEP_LAST" =~ ^[1-9][0-9]*$ ]]; then
    echo "ERROR: KEEP_LAST must be a positive integer." >&2
    exit 1
fi

if ! docker inspect "$REGISTRY_CONTAINER" >/dev/null 2>&1; then
    echo "ERROR: Registry container not found: $REGISTRY_CONTAINER" >&2
    exit 1
fi

REGISTRY_URL="${REGISTRY_SCHEME}://${REGISTRY_ADDRESS}"

DETAIL_REPORT="$REPORT_FILE"
SUMMARY_REPORT="${SCRIPT_DIR}/registry-retention-summary.tsv"

AUTH_ARGS=()

if [[ -n "${REGISTRY_USERNAME:-}" ]]; then
    AUTH_ARGS=(
        --user "${REGISTRY_USERNAME}:${REGISTRY_PASSWORD:-}"
    )
fi

# -------------------------------------------------------------------
# Registry API functions
# -------------------------------------------------------------------

api_get() {
    local url="$1"
    local response_file
    local http_status

    response_file="$(mktemp)"

    http_status="$(
        curl \
            "${AUTH_ARGS[@]}" \
            --silent \
            --show-error \
            --output "$response_file" \
            --write-out '%{http_code}' \
            "$url" ||
        true
    )"

    if [[ "$http_status" != "200" ]]; then
        echo "ERROR: Registry API request failed." >&2
        echo "URL: $url" >&2
        echo "HTTP status: ${http_status:-curl-error}" >&2
        echo "Response:" >&2
        cat "$response_file" >&2
        echo >&2

        rm -f "$response_file"
        return 1
    fi

    cat "$response_file"
    rm -f "$response_file"
}

get_digest() {
    local repository="$1"
    local tag="$2"
    local response_headers
    local digest

    response_headers="$(mktemp)"

    if ! curl \
        "${AUTH_ARGS[@]}" \
        --fail \
        --silent \
        --show-error \
        --head \
        -H 'Accept: application/vnd.oci.image.index.v1+json' \
        -H 'Accept: application/vnd.oci.image.manifest.v1+json' \
        -H 'Accept: application/vnd.docker.distribution.manifest.list.v2+json' \
        -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' \
        --output "$response_headers" \
        "${REGISTRY_URL}/v2/${repository}/manifests/${tag}"
    then
        rm -f "$response_headers"
        return 1
    fi

    digest="$(
        awk -F': ' '
            BEGIN {
                IGNORECASE = 1
            }

            tolower($1) == "docker-content-digest" {
                gsub("\r", "", $2)
                print $2
            }
        ' "$response_headers" |
        tail -n 1
    )"

    rm -f "$response_headers"

    printf '%s\n' "$digest"
}

get_tag_time() {
    local repository="$1"
    local tag="$2"
    local link_file

    link_file="${REGISTRY_REPOSITORIES_PATH}/${repository}/_manifests/tags/${tag}/current/link"

    docker exec "$REGISTRY_CONTAINER" \
        stat -c $'%Y\t%y' "$link_file" 2>/dev/null ||
    true
}

# -------------------------------------------------------------------
# Initial information
# -------------------------------------------------------------------

echo "Registry: ${REGISTRY_URL}"
echo "Container: ${REGISTRY_CONTAINER}"
echo "Keeping latest ${KEEP_LAST} unique digest(s) per repository"
echo
echo "Reading Registry catalog..." >&2

# Do not use ?n=10000 because some Registry versions reject it.
catalog_json="$(
    api_get "${REGISTRY_URL}/v2/_catalog"
)"

mapfile -t repositories < <(
    jq -r '
        .repositories[]?
        | select(type == "string")
        | select(length > 0)
    ' <<< "$catalog_json" |
    sort -u
)

repository_count="${#repositories[@]}"

if [[ "$repository_count" -eq 0 ]]; then
    echo "No repositories found."
    exit 0
fi

mkdir -p "$(dirname "$DETAIL_REPORT")"
mkdir -p "$(dirname "$SUMMARY_REPORT")"

printf "action\trepository\ttag\tpushed_epoch\tpushed_at\tdigest\n" \
    > "$DETAIL_REPORT"

printf "repository\ttotal_tags\tunique_digests\tkeep_tags\tdelete_tags\treview_tags\n" \
    > "$SUMMARY_REPORT"

# -------------------------------------------------------------------
# Global counters
# -------------------------------------------------------------------

total_tags=0
total_unique_digests=0
total_keep_latest=0
total_keep_previous=0
total_delete_candidates=0
total_review=0

# -------------------------------------------------------------------
# Scan repositories
# -------------------------------------------------------------------

for repository in "${repositories[@]}"; do
    echo "Scanning: ${repository}" >&2

    tags_json="$(
        api_get "${REGISTRY_URL}/v2/${repository}/tags/list" ||
        true
    )"

    if [[ -z "$tags_json" ]]; then
        echo "WARNING: Unable to retrieve tags for ${repository}" >&2

        printf "%s\t0\t0\t0\t0\t0\n" \
            "$repository" >> "$SUMMARY_REPORT"

        continue
    fi

    mapfile -t tags < <(
        jq -r '
            .tags[]?
            | select(type == "string")
            | select(length > 0)
        ' <<< "$tags_json" |
        sort -u
    )

    repository_tag_count="${#tags[@]}"

    if [[ "$repository_tag_count" -eq 0 ]]; then
        printf "%s\t0\t0\t0\t0\t0\n" \
            "$repository" >> "$SUMMARY_REPORT"

        continue
    fi

    temp_file="$(mktemp)"
    sorted_file="${temp_file}.sorted"

    for tag in "${tags[@]}"; do
        total_tags=$((total_tags + 1))

        stat_result="$(get_tag_time "$repository" "$tag")"

        pushed_epoch=""
        pushed_at=""

        if [[ -n "$stat_result" ]]; then
            IFS=$'\t' read -r pushed_epoch pushed_at <<< "$stat_result"
        fi

        digest="$(get_digest "$repository" "$tag" || true)"

        if [[ -z "$pushed_epoch" ]]; then
            pushed_epoch="0"
        fi

        if [[ -z "$pushed_at" ]]; then
            pushed_at="unknown"
        fi

        if [[ -z "$digest" ]]; then
            digest="unknown"
        fi

        printf "%s\t%s\t%s\t%s\n" \
            "$pushed_epoch" \
            "$tag" \
            "$pushed_at" \
            "$digest" \
            >> "$temp_file"
    done

    # Newest tag reference first.
    sort \
        -t $'\t' \
        -k1,1nr \
        -k2,2 \
        "$temp_file" \
        > "$sorted_file"

    declare -A digest_rank=()

    repository_unique_digests=0
    repository_keep_tags=0
    repository_delete_tags=0
    repository_review_tags=0

    while IFS=$'\t' read -r pushed_epoch tag pushed_at digest; do
        action=""

        if [[ "$digest" == "unknown" || "$pushed_epoch" == "0" ]]; then
            action="REVIEW"

            repository_review_tags=$((repository_review_tags + 1))
            total_review=$((total_review + 1))
        else
            if [[ -z "${digest_rank[$digest]:-}" ]]; then
                repository_unique_digests=$((repository_unique_digests + 1))
                digest_rank["$digest"]="$repository_unique_digests"
            fi

            rank="${digest_rank[$digest]}"

            if [[ "$rank" -eq 1 ]]; then
                action="KEEP-LATEST"

                repository_keep_tags=$((repository_keep_tags + 1))
                total_keep_latest=$((total_keep_latest + 1))
            elif [[ "$rank" -le "$KEEP_LAST" ]]; then
                action="KEEP-PREVIOUS"

                repository_keep_tags=$((repository_keep_tags + 1))
                total_keep_previous=$((total_keep_previous + 1))
            else
                action="DELETE-CANDIDATE"

                repository_delete_tags=$((repository_delete_tags + 1))
                total_delete_candidates=$((total_delete_candidates + 1))
            fi
        fi

        printf "%s\t%s\t%s\t%s\t%s\t%s\n" \
            "$action" \
            "$repository" \
            "$tag" \
            "$pushed_epoch" \
            "$pushed_at" \
            "$digest" \
            >> "$DETAIL_REPORT"

    done < "$sorted_file"

    # Correct Bash arithmetic syntax.
    total_unique_digests=$((total_unique_digests + repository_unique_digests))

    printf "%s\t%s\t%s\t%s\t%s\t%s\n" \
        "$repository" \
        "$repository_tag_count" \
        "$repository_unique_digests" \
        "$repository_keep_tags" \
        "$repository_delete_tags" \
        "$repository_review_tags" \
        >> "$SUMMARY_REPORT"

    unset digest_rank

    rm -f "$temp_file" "$sorted_file"
done

# -------------------------------------------------------------------
# Calculate final statistics
# -------------------------------------------------------------------

unique_delete_digests="$(
    awk -F'\t' '
        NR > 1 &&
        $1 == "DELETE-CANDIDATE" &&
        $6 != "" &&
        $6 != "unknown" {
            print $2 "\t" $6
        }
    ' "$DETAIL_REPORT" |
    sort -u |
    wc -l
)"

repositories_with_delete_candidates="$(
    awk -F'\t' '
        NR > 1 && ($5 + 0) > 0 {
            print $1
        }
    ' "$SUMMARY_REPORT" |
    wc -l
)"

total_kept_tags=$((total_keep_latest + total_keep_previous))

# -------------------------------------------------------------------
# Print overall summary
# -------------------------------------------------------------------

echo
echo "============================================================"
echo "Registry retention dry-run completed"
echo "============================================================"

printf "%-35s %s\n" "Registry repositories:" "$repository_count"
printf "%-35s %s\n" "Total tags scanned:" "$total_tags"
printf "%-35s %s\n" "Total unique digests:" "$total_unique_digests"
printf "%-35s %s\n" "KEEP-LATEST tags:" "$total_keep_latest"
printf "%-35s %s\n" "KEEP-PREVIOUS tags:" "$total_keep_previous"
printf "%-35s %s\n" "Total kept tags:" "$total_kept_tags"
printf "%-35s %s\n" "DELETE candidate tags:" "$total_delete_candidates"
printf "%-35s %s\n" "Unique delete digests:" "$unique_delete_digests"
printf "%-35s %s\n" \
    "Repositories with deletions:" \
    "$repositories_with_delete_candidates"
printf "%-35s %s\n" "REVIEW required:" "$total_review"

# -------------------------------------------------------------------
# Per-repository summary
# -------------------------------------------------------------------

echo
echo "============================================================"
echo "Repository tag summary"
echo "============================================================"

printf "%-62s %8s %9s %8s %8s %8s\n" \
    "REPOSITORY" \
    "TAGS" \
    "DIGESTS" \
    "KEEP" \
    "DELETE" \
    "REVIEW"

printf "%-62s %8s %9s %8s %8s %8s\n" \
    "--------------------------------------------------------------" \
    "--------" \
    "---------" \
    "--------" \
    "--------" \
    "--------"

tail -n +2 "$SUMMARY_REPORT" |
sort \
    -t $'\t' \
    -k2,2nr \
    -k1,1 |
awk -F'\t' '
    {
        printf "%-62s %8s %9s %8s %8s %8s\n",
               $1, $2, $3, $4, $5, $6
    }
'

# -------------------------------------------------------------------
# Repositories with deletion candidates
# -------------------------------------------------------------------

echo
echo "============================================================"
echo "Repositories with more than ${KEEP_LAST} unique digests"
echo "============================================================"

found_large_repository=0

while IFS=$'\t' read -r \
    repository \
    tag_count \
    digest_count \
    keep_count \
    delete_count \
    review_count
do
    if (( digest_count > KEEP_LAST )); then
        found_large_repository=1

        printf "%-62s tags=%-5s digests=%-5s delete=%s\n" \
            "$repository" \
            "$tag_count" \
            "$digest_count" \
            "$delete_count"
    fi
done < <(
    tail -n +2 "$SUMMARY_REPORT" |
    sort \
        -t $'\t' \
        -k3,3nr \
        -k1,1
)

if [[ "$found_large_repository" -eq 0 ]]; then
    echo "No repository has more than ${KEEP_LAST} unique digests."
fi

# -------------------------------------------------------------------
# Exact delete candidates
# -------------------------------------------------------------------

echo
echo "============================================================"
echo "Delete candidates"
echo "============================================================"

if [[ "$total_delete_candidates" -eq 0 ]]; then
    echo "No delete candidates found."
else
    awk -F'\t' '
        NR > 1 && $1 == "DELETE-CANDIDATE" {
            printf "Repository : %s\n", $2
            printf "Image      : %s:%s\n", $2, $3
            printf "Tag        : %s\n", $3
            printf "Pushed at  : %s\n", $5
            printf "Digest     : %s\n", $6
            printf "%s\n",
                   "------------------------------------------------------------"
        }
    ' "$DETAIL_REPORT"
fi

# -------------------------------------------------------------------
# Exact kept images
# -------------------------------------------------------------------

echo
echo "============================================================"
echo "Images that will be kept"
echo "============================================================"

awk -F'\t' '
    NR > 1 &&
    ($1 == "KEEP-LATEST" || $1 == "KEEP-PREVIOUS") {
        printf "%-14s %-75s %s\n",
               $1,
               $2 ":" $3,
               $6
    }
' "$DETAIL_REPORT"

# -------------------------------------------------------------------
# Review items
# -------------------------------------------------------------------

if [[ "$total_review" -gt 0 ]]; then
    echo
    echo "============================================================"
    echo "Items requiring manual review"
    echo "============================================================"

    awk -F'\t' '
        NR > 1 && $1 == "REVIEW" {
            printf "Repository : %s\n", $2
            printf "Image      : %s:%s\n", $2, $3
            printf "Pushed at  : %s\n", $5
            printf "Digest     : %s\n", $6
            printf "%s\n",
                   "------------------------------------------------------------"
        }
    ' "$DETAIL_REPORT"
fi

# -------------------------------------------------------------------
# Report paths
# -------------------------------------------------------------------

echo
echo "============================================================"
echo "Report files"
echo "============================================================"
echo "Detailed report : ${DETAIL_REPORT}"
echo "Summary report  : ${SUMMARY_REPORT}"
echo
echo "No manifest, tag, digest, blob, image, or repository was deleted."
EOF

chmod +x /opt/registry-retention/registry-retention-dry-run.sh

برای اجرا دستور زیر را وارد میکنیم:

./registry-retention-dry-run.sh

مثال خروجی:

[root@node1 registry-retention]# ./registry-retention-dry-run.sh
Registry: http://10.10.10.99:5000
Container: registry
Keeping latest 2 unique digest(s) per repository

Reading Registry catalog...
Scanning: appsan-back-crm
Scanning: appsan-back-panel
Scanning: appsan-panel-ui
Scanning: auth-server
Scanning: bitnami/os-shell
Scanning: bitnami/postgresql
Scanning: bitnami/rabbitmq-cluster-operator
Scanning: bitnami/redis
Scanning: bitnami/redis-sentinel
Scanning: busybox
Scanning: customer-service-counter-miniapp
Scanning: data-foundation-panel-backend
Scanning: data-foundation-panel-backend-with-path
Scanning: data-foundation-panel-ui
Scanning: data-quality-control
Scanning: devops-fileserver
Scanning: energy-man
Scanning: engine
Scanning: esb-sum-tester
Scanning: fileserver
Scanning: flyway
Scanning: flyway/flyway
Scanning: form-man-miniapp
Scanning: fx-obligation-manager-diba-miniapp
Scanning: haj-multi-messanger
Scanning: haj-pilgrim-search
Scanning: keycloak
Scanning: log-correlator
Scanning: log-management
Scanning: mavaracrm-engine
Scanning: ms-common
Scanning: ms-datatools
Scanning: ms-system
Scanning: newfxs
Scanning: newfxsamd
Scanning: noiro/aci-containers-controller
Scanning: noiro/aci-containers-host
Scanning: noiro/cnideploy
Scanning: noiro/openvswitch
Scanning: noiro/opflex
Scanning: openapi-parser
Scanning: panel-ui
Scanning: pilgrim-search-miniapp
Scanning: pilgrim_search-miniapp
Scanning: pricing-panel-ui
Scanning: pricing-with-feign
Scanning: pricing-with-feign-dev
Scanning: quay.io/frrouting/frr
Scanning: quay.io/jetstack/cert-manager-cainjector
Scanning: quay.io/jetstack/cert-manager-controller
Scanning: quay.io/jetstack/cert-manager-startupapicheck
Scanning: quay.io/jetstack/cert-manager-webhook
Scanning: quay.io/metallb/controller
Scanning: quay.io/metallb/speaker
Scanning: rabbitmq
Scanning: rancher/calico-cni
Scanning: rancher/flannel-cni
Scanning: rancher/hyperkube
Scanning: rancher/local-path-provisioner
Scanning: rancher/mirrored-calico-ctl
Scanning: rancher/mirrored-calico-kube-controllers
Scanning: rancher/mirrored-calico-node
Scanning: rancher/mirrored-calico-pod2daemon-flexvol
Scanning: rancher/mirrored-cluster-proportional-autoscaler
Scanning: rancher/mirrored-coredns-coredns
Scanning: rancher/mirrored-coreos-etcd
Scanning: rancher/mirrored-flannel-flannel
Scanning: rancher/mirrored-ingress-nginx-kube-webhook-certgen
Scanning: rancher/mirrored-k8s-dns-dnsmasq-nanny
Scanning: rancher/mirrored-k8s-dns-kube-dns
Scanning: rancher/mirrored-k8s-dns-node-cache
Scanning: rancher/mirrored-k8s-dns-sidecar
Scanning: rancher/mirrored-metrics-server
Scanning: rancher/mirrored-nginx-ingress-controller-defaultbackend
Scanning: rancher/mirrored-pause
Scanning: rancher/nginx-ingress-controller
Scanning: rancher/rke-tools
Scanning: redis
Scanning: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner
Scanning: rest-interface
Scanning: rest-invoker
Scanning: service-desk
Scanning: soap-invoker
Scanning: soap-parser
Scanning: soft-asset-man-miniapp
Scanning: software-identity-miniapp
Scanning: sso_keycloak
Scanning: timberio/vector

============================================================
Registry retention dry-run completed
============================================================
Registry repositories:           88
Total tags scanned:              112
Total unique digests:            110
KEEP-LATEST tags:                88
KEEP-PREVIOUS tags:              23
DELETE candidate tags:           1
Unique delete digests:           1
Repositories with deletions:     1
REVIEW required:                 0

============================================================
Repository tag summary
============================================================
REPOSITORY                                                  TAGS  DIGESTS     KEEP   DELETE   REVIEW
------------------------------------------------------- -------- -------- -------- -------- --------
data-foundation-panel-backend                                  3        3        2        1        0
bitnami/os-shell                                               2        2        2        0        0
bitnami/redis                                                  2        2        2        0        0
data-foundation-panel-backend-with-path                        2        2        2        0        0
data-foundation-panel-ui                                       2        2        2        0        0
data-quality-control                                           2        2        2        0        0
devops-fileserver                                              2        2        2        0        0
haj-multi-messanger                                            2        2        2        0        0
haj-pilgrim-search                                             2        2        2        0        0
keycloak                                                       2        2        2        0        0
ms-system                                                      2        2        2        0        0
openapi-parser                                                 2        2        2        0        0
panel-ui                                                       2        2        2        0        0
pricing-panel-ui                                               2        2        2        0        0
pricing-with-feign-dev                                         2        2        2        0        0
rest-interface                                                 2        2        2        0        0
rest-invoker                                                   2        2        2        0        0
service-desk                                                   2        2        2        0        0
software-identity-miniapp                                      2        2        2        0        0
timberio/vector                                                2        2        2        0        0
appsan-back-crm                                                1        1        1        0        0
appsan-back-panel                                              1        1        1        0        0
appsan-panel-ui                                                1        1        1        0        0
auth-server                                                    1        1        1        0        0
bitnami/postgresql                                             1        1        1        0        0
bitnami/rabbitmq-cluster-operator                              1        1        1        0        0
bitnami/redis-sentinel                                         1        1        1        0        0
busybox                                                        1        1        1        0        0
customer-service-counter-miniapp                               1        1        1        0        0
energy-man                                                     1        1        1        0        0
engine                                                         1        1        1        0        0
esb-sum-tester                                                 1        1        1        0        0
fileserver                                                     1        1        1        0        0
flyway                                                         1        1        1        0        0
flyway/flyway                                                  1        1        1        0        0
form-man-miniapp                                               1        1        1        0        0
fx-obligation-manager-diba-miniapp                             1        1        1        0        0
log-correlator                                                 1        1        1        0        0
log-management                                                 1        1        1        0        0
mavaracrm-engine                                               1        1        1        0        0
ms-common                                                      1        1        1        0        0
ms-datatools                                                   1        1        1        0        0
newfxs                                                         1        1        1        0        0
newfxsamd                                                      1        1        1        0        0
noiro/aci-containers-controller                                1        1        1        0        0
noiro/aci-containers-host                                      1        1        1        0        0
noiro/cnideploy                                                1        1        1        0        0
noiro/openvswitch                                              1        1        1        0        0
noiro/opflex                                                   1        1        1        0        0
pilgrim-search-miniapp                                         1        1        1        0        0
pilgrim_search-miniapp                                         1        1        1        0        0
quay.io/frrouting/frr                                          1        1        1        0        0
quay.io/jetstack/cert-manager-cainjector                       1        1        1        0        0
quay.io/jetstack/cert-manager-controller                       1        1        1        0        0
quay.io/jetstack/cert-manager-startupapicheck                  1        1        1        0        0
quay.io/jetstack/cert-manager-webhook                          1        1        1        0        0
quay.io/metallb/controller                                     1        1        1        0        0
quay.io/metallb/speaker                                        1        1        1        0        0
rabbitmq                                                       1        1        1        0        0
rancher/calico-cni                                             1        1        1        0        0
rancher/flannel-cni                                            1        1        1        0        0
rancher/hyperkube                                              1        1        1        0        0
rancher/local-path-provisioner                                 1        1        1        0        0
rancher/mirrored-calico-ctl                                    1        1        1        0        0
rancher/mirrored-calico-kube-controllers                       1        1        1        0        0
rancher/mirrored-calico-node                                   1        1        1        0        0
rancher/mirrored-calico-pod2daemon-flexvol                     1        1        1        0        0
rancher/mirrored-cluster-proportional-autoscaler               1        1        1        0        0
rancher/mirrored-coredns-coredns                               1        1        1        0        0
rancher/mirrored-coreos-etcd                                   1        1        1        0        0
rancher/mirrored-flannel-flannel                               1        1        1        0        0
rancher/mirrored-ingress-nginx-kube-webhook-certgen            1        1        1        0        0
rancher/mirrored-k8s-dns-dnsmasq-nanny                         1        1        1        0        0
rancher/mirrored-k8s-dns-kube-dns                              1        1        1        0        0
rancher/mirrored-k8s-dns-node-cache                            1        1        1        0        0
rancher/mirrored-k8s-dns-sidecar                               1        1        1        0        0
rancher/mirrored-metrics-server                                1        1        1        0        0
rancher/mirrored-nginx-ingress-controller-defaultbackend        1        1        1        0        0
rancher/mirrored-pause                                         1        1        1        0        0
rancher/nginx-ingress-controller                               1        1        1        0        0
rancher/rke-tools                                              1        1        1        0        0
redis                                                          1        1        1        0        0
registry.k8s.io/sig-storage/nfs-subdir-external-provisioner        1        1        1        0        0
soap-invoker                                                   1        1        1        0        0
soap-parser                                                    1        1        1        0        0
soft-asset-man-miniapp                                         1        1        1        0        0
sso_keycloak                                                   1        1        1        0        0
repository                                              total_tags unique_digests keep_tags delete_tags review_tags

============================================================
Repositories with more than 2 unique digests
============================================================
data-foundation-panel-backend                           tags=3     digests=3     delete=1

============================================================
Delete candidates
============================================================
Repository : data-foundation-panel-backend
Image      : data-foundation-panel-backend:null
Tag        : null
Pushed at  : 2026-03-28 21:28:29.616459450 +0000
Digest     : sha256:e5d8350338ebb63631b2c2c5bfa781b3b59981c73e03352a592f8f794b651e3b
------------------------------------------------------------

============================================================
Images that will be kept
============================================================
KEEP-LATEST    appsan-back-crm:5f9c84e                                           sha256:1070a842b50327dec4bc247bd4b4ddecd7e616d3e32e82a5028534d550ddf61d
KEEP-LATEST    appsan-back-panel:5f9c84e                                         sha256:cae08d283dfd2eebb9613ec0cf9440935f2b9917b7eba3ed013c1433322a4a01
KEEP-LATEST    appsan-panel-ui:4eb4a27                                           sha256:5d57ac29ccb0ecdf00eb71911afea357ef0ff8a8f5afaac7a7b8fbe5c1fed801
KEEP-LATEST    auth-server:c5d2277                                               sha256:3f16471e046bd284329f3b0b713054c8c45d4838c562054a4d1ce83e95f71190
KEEP-LATEST    bitnami/os-shell:12-debian-12-r40                                 sha256:86282b491360476e192fbd68a25b1f92ca9282e637f432599057d0a311340e56
KEEP-PREVIOUS  bitnami/os-shell:12-debian-12-r24                                 sha256:399baf4d3dc5d2967f7ed95b07a6e48e8faf856c9a8ccf83601ccc4f5221d7e6
KEEP-LATEST    bitnami/postgresql:16.3.0-debian-12-r19                           sha256:33d97c701ceaf71641532e1fce98dcf3b12f7aacbba68aa4da5dc103edd4ec33
KEEP-LATEST    bitnami/rabbitmq-cluster-operator:latest                          sha256:8d9f0ce53c7518327e870a9d6ca2aa3f9faa56c7c9692533a733a753a04868d6
KEEP-LATEST    bitnami/redis:7.4.2-debian-12-r6                                  sha256:233e80ba5fc68b959f34ba5c91ef47caf5a678bf6d0ff19f416539f0122ec304
KEEP-PREVIOUS  bitnami/redis:7.4.1-debian-12-r2                                  sha256:9ea3d45afc7a1bf95192a9591f2debe2ab5e37712a0e456d859e8f450a9cb7ee
KEEP-LATEST    bitnami/redis-sentinel:7.4.2-debian-12-r6                         sha256:8379ae0ba492ebe8d119adf085d5adad29ad7942687d97e581a8c8e36d6d1724
KEEP-LATEST    busybox:latest                                                    sha256:d319b0e3e1745e504544e931cde012fc5470eba649acc8a7b3607402942e5db7
KEEP-LATEST    customer-service-counter-miniapp:ebc7f15                          sha256:fb25defb7f3649eae6bdca6f295b4823eba41dc8c4918be35a8a803e9c2b4799
KEEP-LATEST    data-foundation-panel-backend:d0f5602-fakher                      sha256:bb4481c0c5440b1ddf84f77117c0abfeaa905580abb30aae9de4773ff63fdb08
KEEP-PREVIOUS  data-foundation-panel-backend:61952da-fakher                      sha256:cc2ffe7233376b5619ba7752bdf61afd9c79ba449b112342f33a8218ceae7159
KEEP-LATEST    data-foundation-panel-backend-with-path:9b4bda5-fakher            sha256:86586eafad027c848f7c0091a0db1dee2baba5b9d0addd137c9d356c1fcc51e8
KEEP-PREVIOUS  data-foundation-panel-backend-with-path:b6eb421-fakher            sha256:af2459a1a3c9e81ce4d7eafaa6768988b654ff79d4663998afd6d1080ecd9594
KEEP-LATEST    data-foundation-panel-ui:dfp-ec38808                              sha256:9193cef90b772104f6980c5c62436df4c7967693dd80c2060745840b3df0486d
KEEP-PREVIOUS  data-foundation-panel-ui:dfp-fdc20dd                              sha256:6baddf1a722912681ae77dacbac8e9ce81814b30b4f20191f9dbb768511fed40
KEEP-LATEST    data-quality-control:0826d3b-fakher                               sha256:5b6e5be9a7e761043390f39e2c6d4a12077d5e75a997e77c9fd102a33580ac1a
KEEP-PREVIOUS  data-quality-control:3e3dd03-fakher                               sha256:7869e7beea0428f93735f3fd037a26d73517c0a716d24e3868fd46cf0dc216b9
KEEP-LATEST    devops-fileserver:V12.2                                           sha256:794a758b44bcd7eb4ab1b59e3791232f37b759d2201f1eef67eacdb92bceedd5
KEEP-PREVIOUS  devops-fileserver:V12.1                                           sha256:4bbf0fc9a84d4a3f82004812a9aa8741469a5e98f2c783844548007038a080c9
KEEP-LATEST    energy-man:e89a0b0                                                sha256:e78567dbdbbe25e22ee347ce94b9936ffb16fdeb63b47e632b2b8e5c06516e1e
KEEP-LATEST    engine:5bb50e9                                                    sha256:7970b1b72c7723843f391bb84d716857ce6a783d7647c2b73c67c4b3399a421f
KEEP-LATEST    esb-sum-tester:v1.0                                               sha256:e080d70e1d65225266c0ced477392c682c2e9366118f5a178c61444b2d9303b1
KEEP-LATEST    fileserver:v12.3                                                  sha256:cf9f363e807f110b347d567613e687235bbb3f6d60e40947a93460ea4def8100
KEEP-LATEST    flyway:latest                                                     sha256:fb8e1d3f838527e4b0e9d11228797ddcec4955c4d9b9540ceb521e4e2122dfea
KEEP-LATEST    flyway/flyway:latest                                              sha256:fb8e1d3f838527e4b0e9d11228797ddcec4955c4d9b9540ceb521e4e2122dfea
KEEP-LATEST    form-man-miniapp:65c9e4f                                          sha256:03c86dd369397172405895c617aca2a6630fafcdef8edbecbb97b603f026b7a5
KEEP-LATEST    fx-obligation-manager-diba-miniapp:509c7eb                        sha256:bd6b3f1b6d71930eac9a771f4a5e52b0b636c0efee092413df1b9de4066cf1e9
KEEP-LATEST    haj-multi-messanger:3688422                                       sha256:2f373cbe74dffb363a97f6d185f6938193fb1ebe554d0ee3c46be9ae7f081e93
KEEP-PREVIOUS  haj-multi-messanger:78c0297                                       sha256:43e47661e2a0e4722194779bc228b1948ab184e38d437160169179c69fe26a29
KEEP-LATEST    haj-pilgrim-search:integropia-42                                  sha256:5b0139ca99514d4f68c5babbcd2b346b2c4fe82cecba297981ddb45e0c16f34e
KEEP-PREVIOUS  haj-pilgrim-search:integropia-41                                  sha256:5831ad7934ffe4e630504991d52332fd462d1b0a03b1480d4aec2961fd4f2c1e
KEEP-LATEST    keycloak:itg-26                                                   sha256:e0c89dfbd34ad42e5724e2b7a2e8e6dce008f2cd5438db55601901f187bbc56f
KEEP-PREVIOUS  keycloak:itg-23                                                   sha256:775bb2314f81a0586580a4e85934bd59c0442aa171c2441345f5870a042d1461
KEEP-LATEST    log-correlator:latest                                             sha256:4f0a59dd39b8b56dcbea138eed048c1c281f27b042b315bf8910436d8aef3ce6
KEEP-LATEST    log-management:442ee29                                            sha256:d1540fd13c41316271882e68cd7ba1d8b3997a53af33a7bb799ee4f23cf44732
KEEP-LATEST    mavaracrm-engine:363389e                                          sha256:bdcbafad6b3f431cd0ef61244668dde77f835bc497402549064673d307a64a83
KEEP-LATEST    ms-common:e1a4646                                                 sha256:6c84b8603830f9c02de2ca6e458f970d27b7a7fb844a8aebe25c1bf531aee4f1
KEEP-LATEST    ms-datatools:96b6805                                              sha256:9565b9c4307ce6751962683f5a28f85abf042ffa2e193afce704cb095e50feeb
KEEP-LATEST    ms-system:itg-4                                                   sha256:912e07235b6f7d6c088d20bd727f2a85c58dc641c4ae31bed4398c0542ea277a
KEEP-PREVIOUS  ms-system:itg-3                                                   sha256:a6a29af68391ba67c99741c12674db88e062d2b6092e2610c1c26623d6208780
KEEP-LATEST    newfxs:latest                                                     sha256:93e548ab1a984799db74acbf0b0486019d0281867263e29b59bd5ff48fec01f8
KEEP-LATEST    newfxsamd:latest                                                  sha256:66a03d56c6c90ce836ed82365dce82c27c873e4f4636af0ad9b6bf88b9fb29d0
KEEP-LATEST    noiro/aci-containers-controller:6.1.1.1.81c2369                   sha256:b7f1ebf49d1c681b8001213f86b39649cd5dc118981b3f6b83771af9ad10d472
KEEP-LATEST    noiro/aci-containers-host:6.1.1.1.81c2369                         sha256:eadeb41433bea5c9461d1a3f70c90be31f7b25517e26fe74b43f95bd68695f40
KEEP-LATEST    noiro/cnideploy:6.1.1.1.81c2369                                   sha256:de30bae131703ad03b9cbbe325543bcced695a5cdb0e0700196046c766ba7823
KEEP-LATEST    noiro/openvswitch:6.1.1.1.81c2369                                 sha256:c07a4073eb3de76beb6271d6408b5d0ce6e59ed85be3b2c36e2bb1aa88f720d4
KEEP-LATEST    noiro/opflex:6.1.1.1.81c2369                                      sha256:eb8f7fb50773dfc09f7a7f55fad80683a7e4f96dec0bc10d8802bf575ebd7527
KEEP-LATEST    openapi-parser:itg-5                                              sha256:621a14ba28154487369d0c36a4c7c66f51a593125831ebb56c5fb9afd2895314
KEEP-PREVIOUS  openapi-parser:integropia-4                                       sha256:44a793f146341d67df35c1974a25447346454659c5388514f8b44bff32838600
KEEP-LATEST    panel-ui:itg-16                                                   sha256:c2750dc4130d830a728855c6e3806b165f82aa577a410cefdf3248f097ea8823
KEEP-PREVIOUS  panel-ui:itg-15                                                   sha256:1aa1b29a1bee82e06cacb282eac26bb5b310bdba063f8fedfcc6084fa78edce9
KEEP-LATEST    pilgrim-search-miniapp:eb71481                                    sha256:fcdf6a33799a925adb6645a2ff3ff468d105a72cf6b56a3c92e86037afd711b1
KEEP-LATEST    pilgrim_search-miniapp:eb71481                                    sha256:fcdf6a33799a925adb6645a2ff3ff468d105a72cf6b56a3c92e86037afd711b1
KEEP-LATEST    pricing-panel-ui:dfp-72-internal                                  sha256:d38bbf554176dfcd210addbfd6e559610b8dcab23875d42677342411cf0a8511
KEEP-PREVIOUS  pricing-panel-ui:dfp-71-internal                                  sha256:86b4d37d87b265a89c871c64b53dd4ede90411623d1b5366bd46e606df9c7c64
KEEP-LATEST    pricing-with-feign:296d81f-fakher                                 sha256:1f9fffd92889bede2ff9d6b1c25542db2d439cdc878b829407ea6516f156a3d2
KEEP-PREVIOUS  pricing-with-feign:b068181-fakher                                 sha256:4b4dc316210fa15e49b07ef88912071b45c11ac11265e849cccc8dc9d2bcec85
KEEP-PREVIOUS  pricing-with-feign:4641768-fakher                                 sha256:4b4dc316210fa15e49b07ef88912071b45c11ac11265e849cccc8dc9d2bcec85
KEEP-PREVIOUS  pricing-with-feign:0c5882d-fakher                                 sha256:4b4dc316210fa15e49b07ef88912071b45c11ac11265e849cccc8dc9d2bcec85
KEEP-LATEST    pricing-with-feign-dev:ac6d1ed-fakher                             sha256:020f8cb6170891c85299031a2a58c1679cedc8c1f2000031e49c30797f8266ab
KEEP-PREVIOUS  pricing-with-feign-dev:fa1a824-fakher                             sha256:06fb7831f3172f96265088a83e74783fcff4f6ac0f065dc1e70aa0b864206e2f
KEEP-LATEST    quay.io/frrouting/frr:9.1.0                                       sha256:e9eef6f1be059274fc1280f54eea41ebf1db36c9e1a22d454c72ee08583c1f07
KEEP-LATEST    quay.io/jetstack/cert-manager-cainjector:v1.16.1                  sha256:171f9a9a7affd5905e509a52f13a7cae75b2303510e0455fda30a49a4b8847c0
KEEP-LATEST    quay.io/jetstack/cert-manager-controller:v1.16.1                  sha256:8f82029c681ec7812c3dcae27136412d67cb8334e78c3f61a93b301c14802fa8
KEEP-LATEST    quay.io/jetstack/cert-manager-startupapicheck:v1.16.1             sha256:c00bc206b040b4563b72d73a022607e79f73df26de94749e2ec1725d8d9d9b15
KEEP-LATEST    quay.io/jetstack/cert-manager-webhook:v1.16.1                     sha256:71606ab773978c8f0172759bf06b17d268f67cb4fea5303e39d1d29033cc4bb0
KEEP-LATEST    quay.io/metallb/controller:v0.14.8                                sha256:ecf533ca0b175a88f91a767f675c1cc1e5058e675d678d4c2ac9dff45d355c9c
KEEP-LATEST    quay.io/metallb/speaker:v0.14.8                                   sha256:87f1be308b8d42b227a989cf6c13b5d11d4e0611cee06d4f335ca1ff3ab8638b
KEEP-LATEST    rabbitmq:4.0.3-management-alpine                                  sha256:63c260b34b6c657c1273b98a8a5adcf57fde85534fda0fa6698d6865f15847aa
KEEP-LATEST    rancher/calico-cni:v3.28.1-rancher1                               sha256:6270ed548cf1402e1e337f7c5a57a4ee7131386c31e37909cb83aa8e663c8dcd
KEEP-LATEST    rancher/flannel-cni:v1.4.1-rancher1                               sha256:6525affdfa48affc550487d9c7c1f02beed36427854a6424191a0a1bdd7627d2
KEEP-LATEST    rancher/hyperkube:v1.30.5-rancher1                                sha256:a6bdbda952a78af0978ee0b5b6f228dbcba34025a0d0f1581152cc67d8617d88
KEEP-LATEST    rancher/local-path-provisioner:v0.0.26                            sha256:9325057706239e408ed417b19356cd892ee67b046ee08ff11798777d67288bd5
KEEP-LATEST    rancher/mirrored-calico-ctl:v3.28.1                               sha256:deea3c3b5931520f6b77654626053bd265504645b4fa33348c0a2b08ca918dd0
KEEP-LATEST    rancher/mirrored-calico-kube-controllers:v3.28.1                  sha256:8579fad4baca75ce79644db84d6a1e776a3c3f5674521163e960ccebd7206669
KEEP-LATEST    rancher/mirrored-calico-node:v3.28.1                              sha256:f72bd42a299e280eed13231cc499b2d9d228ca2f51f6fd599d2f4176049d7880
KEEP-LATEST    rancher/mirrored-calico-pod2daemon-flexvol:v3.28.1                sha256:72be5fbe1cef7a60245bdc0c9f37f9f92800d115c63760955382d6597ea58e23
KEEP-LATEST    rancher/mirrored-cluster-proportional-autoscaler:v1.8.9           sha256:f7ed92f1e5c511a4ffcf266851db8ddedb45d87d861ced63f3bcfe62b1731051
KEEP-LATEST    rancher/mirrored-coredns-coredns:1.11.1                           sha256:2169b3b96af988cf69d7dd69efbcc59433eb027320eb185c6110e0850b997870
KEEP-LATEST    rancher/mirrored-coreos-etcd:v3.5.12                              sha256:162fe639721588329bfea28d8b5e1286423cebd2b48c789ce7facfe7e0db0e1d
KEEP-LATEST    rancher/mirrored-flannel-flannel:v0.25.1                          sha256:707bb127c71edb8c619a0485d98796fc849eff1618a1214f335df88ed0b5615d
KEEP-LATEST    rancher/mirrored-ingress-nginx-kube-webhook-certgen:v1.4.1        sha256:887b7f4495677473f1bef5bfb48200a1070e526183b515682a7e78e43c7d7da4
KEEP-LATEST    rancher/mirrored-k8s-dns-dnsmasq-nanny:1.23.0                     sha256:5f420006a6da5263570e2c8c35ad133c1f29ea562092af24f0b655be6202d2bb
KEEP-LATEST    rancher/mirrored-k8s-dns-kube-dns:1.23.0                          sha256:32b101995e0742f18af3528b1da23be0e5bb9353f8ed9667ca74cd85d3cc968f
KEEP-LATEST    rancher/mirrored-k8s-dns-node-cache:1.23.0                        sha256:6177e8cdbafa04b5a33df4f3b3bb1d826584e34cfe1dfdb0b773eb8f566b8047
KEEP-LATEST    rancher/mirrored-k8s-dns-sidecar:1.23.0                           sha256:33a513ad5eba3bed82e073c14c778b4951fab04a45d44be00bda1c7354f0a38f
KEEP-LATEST    rancher/mirrored-metrics-server:v0.7.1                            sha256:799bbdcdd394890e7e4564ff692d3e7506e34cbe2117f7e8db867257f6bc6e08
KEEP-LATEST    rancher/mirrored-nginx-ingress-controller-defaultbackend:1.5-rancher1 sha256:4dc5e07c8ca4e23bddb3153737d7b8c556e5fb2f29c4558b7cd6e6df99c512c7
KEEP-LATEST    rancher/mirrored-pause:3.7                                        sha256:445a99db22e9add9bfb15ddb1980861a329e5dff5c88d7eec9cbf08b6b2f4eb1
KEEP-LATEST    rancher/nginx-ingress-controller:nginx-1.11.2-rancher1            sha256:f0402daaa8551afd3342d7cdbe2096e94988bfe4b6519367f676592e475ac9d6
KEEP-LATEST    rancher/rke-tools:v0.1.103                                        sha256:d4d2f8a11901ba950fc61b8e2d0a849b1797796f495a683cd84ca8b521dcb33b
KEEP-LATEST    redis:8.0-M03-alpine3.21                                          sha256:64a6d11ec570f253bf47392d70820cef20ff859fd1f7b150232561d97ddf912b
KEEP-LATEST    registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2 sha256:f741e403b3ca161e784163de3ebde9190905fdbf7dfaa463620ab8f16c0f6423
KEEP-LATEST    rest-interface:be5cb08                                            sha256:d285b34b0fbba68955fe379ed7ff578374bee3b9252bed65838ac48609e47919
KEEP-PREVIOUS  rest-interface:d2ade9b                                            sha256:209cb8b8ddd69dcc92129fb4fdd5784fd75f572e18a8a785135b47f45d5c0c75
KEEP-LATEST    rest-invoker:92290fb                                              sha256:0b112c4e309ccd29b9d45baa3c89a9aaa57d5f5955045ea04231518554a328f2
KEEP-PREVIOUS  rest-invoker:1d409fe                                              sha256:0fc206944ed9d8da616b66ed1f33cd8eca6b8f209baab722166af7dd0ac32c3a
KEEP-LATEST    service-desk:itg-37                                               sha256:b393a8a7246bd7bbabbe2dc3390cf690163d408ee243c048b6a816bd576c858c
KEEP-PREVIOUS  service-desk:itg-36                                               sha256:dd3daa69c29e91bdf78bbbf6f2c649110c940d11d3f521c6ec4be76c1d0763e4
KEEP-LATEST    soap-invoker:223a6b4                                              sha256:de37965e3ae8e684fcbc960706cc198c9ed3045e423f19e79d2b8ef7d8ab9104
KEEP-LATEST    soap-parser:8ad244a                                               sha256:13b974f0c0a65bf0189ee1972be4090e16e021615c5ccd34ff9de946ccf875ad
KEEP-LATEST    soft-asset-man-miniapp:4fd828a                                    sha256:923744bcfd45283425ec52071054e59e03c60802fd51f821e841a908a53c9378
KEEP-LATEST    software-identity-miniapp:1bf69da                                 sha256:b5de488c28110d7affe3a47cb3e1e18733e6740ccb2fe794e228d600f29e99d4
KEEP-PREVIOUS  software-identity-miniapp:1af723e                                 sha256:d17a71413d55e0ffde43f5b965aee62357b67ecd5c454b84b1de1066777460c0
KEEP-LATEST    sso_keycloak:23.0.3-1.0.53                                        sha256:b18ad3dce1631ad3bb8e7747a501dea03c363015e8027c7584d1ae2ebc347fa8
KEEP-LATEST    timberio/vector:0.46.1-debian                                     sha256:b69744ff85f898279be707312546cf6f117192659e5080ffc988c7dca341dfdd
KEEP-PREVIOUS  timberio/vector:0.42.0-debian                                     sha256:e3537b4d454b6711e10c7643268fe5e8f0cc8489d462dc6a46cd01ccea9c89dd

============================================================
Report files
============================================================
Detailed report : /opt/registry-retention/registry-retention-report.tsv
Summary report  : /opt/registry-retention/registry-retention-summary.tsv

No data was deleted.

توجه کنید که این دستور ایمیجی را پاک نکرده و صرفا برای اطمینان و گزارش‌گیری ساخته شده است.