Skip to content

Commit

Permalink
for idaholab#453, allow specifying a maximum gigabytes threshold for …
Browse files Browse the repository at this point in the history
…prune_files.sh
  • Loading branch information
mmguero committed Apr 8, 2024
1 parent e38b00a commit 1a69873
Showing 1 changed file with 38 additions and 28 deletions.
66 changes: 38 additions & 28 deletions shared/bin/prune_files.sh
Original file line number Diff line number Diff line change
@@ -1,53 +1,62 @@
#!/bin/bash
#!/usr/bin/env bash

# Copyright (c) 2024 Battelle Energy Alliance, LLC. All rights reserved.

# recursion depth (1 = not recursive)
DEPTH=1

# threshold is an integer percentage between 1-100; the script will prune until disk usage drops below the threshold
THRESHOLD=90 # defaults to "prune when usage >= 90%";
# THRESHOLD_PCT and MAXSIZE_GB define pruning triggers; either or both may trigger pruning.
# A value of 0 means that trigger is unused
# If either trigger condition matches, the script will prune until disk usage drops **below** the thresholds

# THRESHOLD_PCT is an integer percentage between 1-100 ("prune when disk usage >= THRESHOLD_PCT%")
THRESHOLD_PCT=0
# MAXSIZE_GB is an integer representing gigabytes ("prune when path contents >= MAXSIZE_GB")
MAXSIZE_GB=0

# if specified, this script will check and prune every $INTERVAL seconds
INTERVAL=0 # defaults to "run once then exit"

VERBOSE=0 # defaults to "not verbose"

while getopts t:p:i:rv opts; do
while getopts i:m:p:rt:v opts; do
case ${opts} in
p) PRUNE_PATH=${OPTARG} ;;
t) THRESHOLD=${OPTARG} ;;
i) INTERVAL=${OPTARG} ;;
m) MAXSIZE_GB=${OPTARG} ;;
p) PRUNE_PATH=${OPTARG} ;;
r) DEPTH=999 ;;
t) THRESHOLD_PCT=${OPTARG} ;;
v) VERBOSE=1 ;;
esac
done

INT_RE='^[0-9]+$'

if [ -z $PRUNE_PATH ] || [ ! -e "$PRUNE_PATH" ] || ! pushd >/dev/null 2>&1 $PRUNE_PATH ; then
echo "Please specify prune path with -p"
if [[ -z "$PRUNE_PATH" ]] || [[ ! -e "$PRUNE_PATH" ]] || ! pushd >/dev/null 2>&1 $PRUNE_PATH ; then
echo "Please specify prune path with -p" >&2
exit 1
fi

if [ -z $THRESHOLD ] || [[ ! "$THRESHOLD" =~ $INT_RE ]] || ! [ "$THRESHOLD" -ge 1 -a "$THRESHOLD" -le 100 ] ; then
echo "Please specify prune threshold (percentage, 1-100) with -t"
if [[ ! "$INTERVAL" =~ $INT_RE ]] || ! (( "$INTERVAL" >= 0 && "$INTERVAL" <= 86400 )) ; then
echo "Please specify prune check interval (seconds, 0-86400) with -i (0 = run once)" >&2
exit 1
fi

if [[ ! "$INTERVAL" =~ $INT_RE ]] || ! [ "$INTERVAL" -ge 0 -a "$INTERVAL" -le 86400 ] ; then
echo "Please specify prune check interval (seconds, 0-86400) with -i (0 = run once)"
if ( [[ -z "$THRESHOLD_PCT" ]] || [[ ! "$THRESHOLD_PCT" =~ $INT_RE ]] || ! (( "$THRESHOLD_PCT" >= 1 && "$THRESHOLD_PCT" <= 100)) ) &&
( [[ -z "$MAXSIZE_GB" ]] || [[ ! "$MAXSIZE_GB" =~ $INT_RE ]] || ! (( "$MAXSIZE_GB" >= 1 )) ); then
echo "Please specify at least one prune trigger: threshold (percentage, 1-100) with -t; or, maximum size (gigabytes, >= 1) with -m" >&2
exit 1
fi

while true ; do

# check initial disk capacity
USAGE=$(df -k . | awk '{gsub("%",""); capacity=$5}; END {print capacity}')
if [ $USAGE -gt $THRESHOLD ] ; then
USAGE_PCT=$(df -k . | awk '{gsub("%",""); capacity=$5}; END {print capacity}')
USAGE_GB=$(du -sh --block-size=1G . | awk '{print $1}')
# du -sh --block-size=1G ~/download/ | awk '{print $1}'
if ( (( $THRESHOLD_PCT > 0 )) && (( $USAGE_PCT > $THRESHOLD_PCT )) ) || ( (( $MAXSIZE_GB > 0 )) && (( $USAGE_GB > $MAXSIZE_GB )) ); then

# we have exceeded the threshold, see if there is something to prune
[[ "$VERBOSE" == "1" ]] && echo "\"$PRUNE_PATH\" is at $USAGE% of capacity, pruning..."
[[ "$VERBOSE" == "1" ]] && echo "\"$PRUNE_PATH\" is at $USAGE_PCT% of capacity ($USAGE_GB GB), pruning..." >&2

# read files by modification time, oldest first, deleting until we've dropped below the threshold
DELETED=0
Expand All @@ -56,20 +65,21 @@ while true ; do
FILE_SIZE_HUMAN=$(numfmt --to=iec-i --suffix=B $FILE_SIZE)
FILE_TIME_HUMAN=$(date -u -d @$FILE_TIME)

if [ -f "$FILE_TO_DELETE" ]; then
if [[ -f "$FILE_TO_DELETE" ]]; then
if rm -f "$FILE_TO_DELETE" ; then
DELETED=$((DELETED+1))

echo "Pruned \"$FILE_TO_DELETE\" ($FILE_SIZE_HUMAN, $FILE_TIME_HUMAN)"
echo "Pruned \"$FILE_TO_DELETE\" ($FILE_SIZE_HUMAN, $FILE_TIME_HUMAN)" >&2

# re-check disk capacity
USAGE=$(df -k . | awk '{gsub("%",""); capacity=$5}; END {print capacity}')
if [ $USAGE -gt $THRESHOLD ] ; then
USAGE_PCT=$(df -k . | awk '{gsub("%",""); capacity=$5}; END {print capacity}')
USAGE_GB=$(du -sh --block-size=1G . | awk '{print $1}')
if ( (( $THRESHOLD_PCT > 0 )) && (( $USAGE_PCT > $THRESHOLD_PCT )) ) || ( (( $MAXSIZE_GB > 0 )) && (( $USAGE_GB > $MAXSIZE_GB )) ); then
# we still exceed the threshold, continue to loop
[[ "$VERBOSE" == "1" ]] && echo "\"$PRUNE_PATH\" is at $USAGE% of capacity, pruning..."
[[ "$VERBOSE" == "1" ]] && echo "\"$PRUNE_PATH\" is at $USAGE_PCT% of capacity ($USAGE_GB GB), pruning..." >&2
else
# we're below the limit, break
[[ "$VERBOSE" == "1" ]] && echo "\"$PRUNE_PATH\" is at $USAGE% of capacity"
[[ "$VERBOSE" == "1" ]] && echo "\"$PRUNE_PATH\" is at $USAGE_PCT% of capacity ($USAGE_GB GB)" >&2
break
fi

Expand All @@ -78,18 +88,18 @@ while true ; do

done < <(find . -xdev -mindepth 1 -maxdepth $DEPTH -ignore_readdir_race -type f \( ! -path '*/spool/*' -o -path '*/spool/tmp*' \) -printf '%T@ %s %p\0' 2>/dev/null | sort -zn 2>/dev/null)

if [ $DELETED -gt 0 ] ; then
[[ "$VERBOSE" == "1" ]] && echo "Pruned $DELETED files in \"$PRUNE_PATH\""
if (( $DELETED > 0 )) ; then
[[ "$VERBOSE" == "1" ]] && echo "Pruned $DELETED files in \"$PRUNE_PATH\"" >&2
else
echo "Nothing was pruned in \"$PRUNE_PATH\"!"
echo "Nothing was pruned in \"$PRUNE_PATH\"!" >&2
fi

else
[[ "$VERBOSE" == "1" ]] && echo "\"$PRUNE_PATH\" is at $USAGE% of capacity"
[[ "$VERBOSE" == "1" ]] && echo "\"$PRUNE_PATH\" is at $USAGE_PCT% of capacity ($USAGE_GB GB)" >&2
fi

if [ $INTERVAL -gt 0 ] ; then
sleep $INTERVAL
if (( $INTERVAL > 0 )) ; then
for i in $(seq 1 $INTERVAL); do sleep 1; done
else
break
fi
Expand Down

0 comments on commit 1a69873

Please sign in to comment.