forked from bakerboy448/StarrScripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
zfsburn.sh
executable file
·158 lines (131 loc) · 5.22 KB
/
zfsburn.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/env bash
# Load environment variables from .env file if it exists
# in the same directory as this bash script
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_PATH="$SCRIPT_DIR/.env"
if [ -f "$ENV_PATH" ]; then
# shellcheck source=.env
echo "Loading environment variables from $ENV_PATH file"
# shellcheck disable=SC1090 # shellcheck sucks
if source "$ENV_PATH"; then
echo "Environment variables loaded successfully"
else
echo "Error loading environment variables" >&2
exit 1
fi
else
echo ".env file not found in script directory ($ENV_PATH)"
fi
VERBOSE=${VERBOSE:-1}
MAX_FREQ=${MAX_FREQ:-4}
MAX_HOURLY=${MAX_HOURLY:-2}
MAX_DAILY=${MAX_DAILY:-7}
MAX_WEEKLY=${MAX_WEEKLY:-4}
MAX_MONTHLY=${MAX_MONTHLY:-3}
# Logging function based on verbosity level
log() {
local level="$1"
local message="$2"
if ((level == 0)) || ((VERBOSE == 1 && level == 1)); then
echo "$message"
fi
}
# Bytes to Human Formatting
bytes_to_human_readable() {
local bytes=$1
local units=('B' 'KB' 'MB' 'GB' 'TB' 'PB' 'EB' 'ZB' 'YB')
local unit=0
while ((bytes > 1024)); do
((bytes /= 1024))
((unit++))
done
echo "${bytes} ${units[unit]}"
}
# Function to retrieve snapshot counts for a specific snapshot type
get_snapshot_count() {
local snapshot_type="$1"
local dataset="$2"
local snapshot_count=0
# Filter snapshots based on the snapshot type and count them
snapshot_count=$(sudo zfs list -t snapshot -o name -r "$dataset" | grep -cE "$dataset@.*$snapshot_type-[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{4}$")
# Return the snapshot count as a variable
echo "$snapshot_count"
}
# Function to delete snapshots based on frequency limits
delete_snapshots() {
local dataset="$1"
local snapshots=()
local deleted=0
local space_gained=0
# Retrieve all snapshots for the dataset
readarray -t snapshots < <(sudo zfs list -t snapshot -H -o name -r "$dataset")
# Info log prior to filtering
log 0 "Total snapshots before filtering: [${#snapshots[@]}]"
# Loop through snapshots and delete based on frequency limits
for snapshot in "${snapshots[@]}"; do
log 1 "Filtering snapshot: [$snapshot]"
local snapshot_name=${snapshot##*/}
local snapshot_type=${snapshot_name#*_}
snapshot_type=${snapshot_type%%-*}
if [[ "$snapshot_type" == "frequent" || "$snapshot_type" == "hourly" || "$snapshot_type" == "daily" || "$snapshot_type" == "weekly" || "$snapshot_type" == "monthly" ]]; then
log 0 "Processing snapshot: [$snapshot]"
local max_count=0
local current_count=0
if [[ "$snapshot_type" == "frequent" ]]; then
max_count=$MAX_FREQ
current_count=$frequent_count
elif [[ "$snapshot_type" == "hourly" ]]; then
max_count=$MAX_HOURLY
current_count=$hourly_count
elif [[ "$snapshot_type" == "daily" ]]; then
max_count=$MAX_DAILY
current_count=$daily_count
elif [[ "$snapshot_type" == "weekly" ]]; then
max_count=$MAX_WEEKLY
current_count=$weekly_count
elif [[ "$snapshot_type" == "monthly" ]]; then
max_count=$MAX_MONTHLY
current_count=$monthly_count
fi
log 1 "Current snapshot count: [$current_count]"
log 1 "Maximum allowed: [$max_count]"
if ((current_count > max_count || max_count == 0)); then
log 0 "Deleting snapshot: [$snapshot]"
local snapshot_space
snapshot_space=$(sudo zfs list -o used -H -p "$snapshot" | awk '{print $1}')
if sudo zfs destroy "$snapshot"; then
((deleted++))
((space_gained += snapshot_space))
snapshot_space_formatted=$(bytes_to_human_readable "$snapshot_space")
log 0 "Space gained: $snapshot_space_formatted"
else
log 0 "Error deleting snapshot: [$snapshot]"
fi
fi
else
log 1 "Skipped processing snapshot: [$snapshot] - no match to type: [$snapshot_type]"
fi
done
space_gained_formatted=$(bytes_to_human_readable "$space_gained")
log 0 "Deleted $deleted snapshots for dataset: [$dataset]. Total space gained: $space_gained_formatted"
}
# Usage: ./zfsburn.sh <dataset>
if [[ $# -lt 1 ]]; then
echo "Usage: ./zfsburn.sh <dataset>"
exit 1
fi
# Capture the dataset as a variable
datasets="$1"
# Capture snapshot counts as variables
frequent_count=$(get_snapshot_count "frequent" "$datasets")
hourly_count=$(get_snapshot_count "hourly" "$datasets")
daily_count=$(get_snapshot_count "daily" "$datasets")
weekly_count=$(get_snapshot_count "weekly" "$datasets")
monthly_count=$(get_snapshot_count "monthly" "$datasets")
# Use the snapshot counts as needed in the rest of the script
log 0 "Frequent Snapshot Count: [$frequent_count]"
log 0 "Hourly Snapshot Count: [$hourly_count]"
log 0 "Daily Snapshot Count: [$daily_count]"
log 0 "Weekly Snapshot Count: [$weekly_count]"
log 0 "Monthly Snapshot Count: [$monthly_count]"
delete_snapshots "$datasets"