Skip to content

Instantly share code, notes, and snippets.

@DaniJG
Created August 19, 2021 12:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DaniJG/60190ad032e1ff2f432391b0bff5c415 to your computer and use it in GitHub Desktop.
Save DaniJG/60190ad032e1ff2f432391b0bff5c415 to your computer and use it in GitHub Desktop.
Script that can be used to remove outdated apprevisions
#! /bin/bash
# The scripts needs to run agains the Kubernetes cluster where rancher is installed, make sure to setup your context/credentials for kubectl
# If you run it with no arguments, it will ask you to confirm before looking at each cluster, and before removing app revisions in a given rancher project
# Alternatively run with "--force-yes" and will clean without asking
set -eu
# process arguments. See https://stackoverflow.com/a/24597113/1836935
forceYes=false
for ((i=1;i<=$#;i++));
do
if [ ${!i} = "--force-yes" ]
then forceYes=true;
# In case we ever add a parameter that has an argument like "-s foo"
# elif [ ${!i} = "-s" ]
# then ((i++))
# var1=${!i};
fi
done;
# get list of clusters
clusters=$(kubectl get cluster --no-headers=true | awk '{print $1}')
for cluster in $clusters
do
echo "Processing cluster $cluster"
# ask for explicit confirmation before looking at cluster
if [[ "$forceYes" == "false" ]]; then
read -p "Do you want to proceed? only yes will be accepted"$'\n' answer
if [[ ! $answer =~ ^yes$ ]]; then
continue
fi
fi
# get list of all projects in the cluster
# NOTE: can get all prokects in any cluster using --all-namespaces
# however this way the user can explicitly run cleanup on specific clusters
# projects=$(kubectl get project --no-headers=true --all-namespaces | awk '{print $2}')
projects=$(kubectl get project --no-headers=true -n $cluster | awk '{print $1}')
for project in $projects
do
echo "Processing project $cluster:$project"
appCount=$(kubectl -n $project get app --ignore-not-found --no-headers=true | wc -l)
if [[ ! $appCount > 0 ]]; then
echo "no apps in the project"
continue
fi
# get the total app revision count
apprevisionCount=$(kubectl -n $project get apprevision --no-headers=true | wc -l)
# get the current app revision names
# To do so, get the field ".spec.appRevisionName" of every installed app (where the field exists)
# We get them in a "|" delimited string so its easier to use a parameter for awk (with a negative regex match we can then get all non-current app revisions)
currentAppRevisions=$(kubectl -n $project get app -o jsonpath='{range .items[?(@.spec.appRevisionName)]}{.spec.appRevisionName}{"|"}{end}{"\n"}')
currentAppRevisions=${currentAppRevisions:0:-1}
# get the count of apprevisions that are neither of the current app revisions (ie, the count of revisions to delete)
oldAppRevisionsCount=$(kubectl -n $project get apprevision --no-headers=true | awk -v regex=$currentAppRevisions '$0 !~ regex {print $1}' | wc -l)
# Let the user review the numbers of apps and apprevisions and confirm if they want to proceed
echo "Project $cluster:$project:"
echo " Total apps=$appCount"
echo " Total revisions=$apprevisionCount"
echo " Revisions to remove=$oldAppRevisionsCount"
if [[ ! $oldAppRevisionsCount > 0 ]]; then
echo "no outdated apprevisions to remove in the project"
continue
fi
# ask for explicit confirmation before cleaning revisions for this project
if [[ "$forceYes" == "false" ]]; then
read -p "Do you want to proceed? only yes will be accepted"$'\n' answer
if [[ ! $answer =~ ^yes$ ]]; then
continue
fi
fi
# If confirmed, delete all non-current apprevisions
kubectl -n $project get apprevision --no-headers=true | awk -v regex=$currentAppRevisions '$0 !~ regex {print $1}' | xargs kubectl -n $project delete apprevision
done
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment