-
Notifications
You must be signed in to change notification settings - Fork 0
/
vm-retention-policy
129 lines (89 loc) · 5.22 KB
/
vm-retention-policy
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
#!/bin/bash
show_help()
{
cat << end_of_help
USAGE: $(basename $0) [-h | --help] <[--force] domain1 domain2...>
$(basename $0) -- Applies Backup Rotation and Retention Policy.
- Checks backups lifecyle based on MAX_BACKUPS_PER_CHAIN, triggering its archiving when reaches that number of checkpoints
- Applies retention policy, based on LOCAL|RSYNC_BACKUP_CHAINS_TO_KEEP, keeping as many (and most recent) backup chains on each endpoint, deleting the older ones.
- When '--force'is passed as the first argument, overrides MAX_BACKUPS_PER_CHAIN and triggers its immediate archiving.
end_of_help
}
if [[ $1 == "-h" || $1 == "--help" ]]; then
# Show help and exit:
show_help
exit
elif [[ $1 == "--force" ]]; then
# Force the end of lifecycle:
retention_mode="Forced"
shift
elif [[ -n $MAX_BACKUPS_PER_CHAIN && $MAX_BACKUPS_PER_CHAIN -gt 0 ]]; then
# Run normal checks and apply retention policy:
retention_mode="Normal"
fi
# Load common functions:
source /usr/local/bin/vm-functions
# Processes initial backups list from VMs (passed as arguments):
retention_list=($@)
if [[ -n ${retention_list[@]} ]]; then
for domain in ${retention_list[@]}; do
# (Re)Initialize boolean variables:
local_backup_not_found=""
end_of_lifecycle=""
# Display screen divider when processing several backup chains:
[[ ${#retention_list[@]} -gt 1 ]] \
&& screen_header "-"
if [[ -d $LOCAL_BACKUP_PATH/$domain \
&& -n $(ls -A $LOCAL_BACKUP_PATH/$domain) \
&& -n $(list_extensions $LOCAL_BACKUP_PATH/$domain | grep -iv log) ]]; then
echo "$domain: Checking backup chain lifecycle..."
# Backup path exists, is not empty and has something aside logs. Proceed with check:
# Retention policy is set (at least, partially) by the user. Retrieve the number of existing checkpoints in the backup chain:
num_of_backup_checkpoints=$(backup_checkpoints_num $LOCAL_BACKUP_PATH/$domain)
case $retention_mode in
Normal) # Will check how many checkpoints will have, marking the end of its lifecycle if cannot be used
if [[ $num_of_backup_checkpoints -eq 0 ]]; then
# '0' checkpoints means it's a 'copy' backup:
end_of_lifecycle=true
echo "$domain: Chainless backup made using 'copy' mode. It cannot be used to store incremental backups"
elif [[ $num_of_backup_checkpoints -ge $MAX_BACKUPS_PER_CHAIN ]]; then
end_of_lifecycle=true
echo "$domain: Backup chain has reached the end of its lifecycle and must be rotated ($num_of_backup_checkpoints of $MAX_BACKUPS_PER_CHAIN allowed checkpoints)"
else
end_of_lifecycle=false
echo "$domain: Backup chain currently contains $num_of_backup_checkpoints of $MAX_BACKUPS_PER_CHAIN allowed checkpoints"
fi
;;
Forced) # No checks will be performed. Directly end its lifecycle
echo "$domain: Backup chain has been forcibly set to end its lifecycle and must be rotated ($num_of_backup_checkpoints of $MAX_BACKUPS_PER_CHAIN allowed checkpoints)"
end_of_lifecycle=true
;;
*) # MAX_BACKUPS_PER_CHAIN is not set, or value is 0:
echo "WARNING: $domain: Data retention policy is disabled ($num_of_backup_checkpoints) checkpoints so far)"
;;
esac
if [[ $end_of_lifecycle == true ]]; then
# Process local backup chain if it has reached its lifecycle (for whatever reason):
archive_backup $LOCAL_BACKUP_PATH/$domain $LOCAL_BACKUP_CHAINS_TO_KEEP
fi
else
echo "$domain: No backup found at $LOCAL_BACKUP_PATH"
# Mark local backup as 'not found' (to perform tasks below):
local_backup_not_found=true
fi
if [[ -n $RSYNC_BACKUP_PATH ]] && [[ $end_of_lifecycle == true || $local_backup_not_found == true ]]; then
# Process rsync mirror, discerning if located at local or remote (SSH) path:
[[ $RSYNC_BACKUP_PATH == *@*:/* ]] && archive_command="archive_remote_backup" || archive_command="archive_backup"
# Also discerning if local backup was not found in first instance,
# in which case any remote mirror that exists will be archived, but no retention policy applied with old backup chains:
[[ $local_backup_not_found == true ]] && rsync_retention="" || rsync_retention=$RSYNC_BACKUP_CHAINS_TO_KEEP
# In order to archive and apply (or not) retention policy on the mirror:
$archive_command $RSYNC_BACKUP_PATH/$domain $rsync_retention
fi
done
# When multiple backups chains were processed, display that the script has finished:
[[ ${#retention_list[@]} -gt 1 ]] \
&& echo -e "\n$(basename $0): Finished\n"
else
echo -e "No flags and/or domain(s) passed as arguments to check backup lifecycle or apply data retention policy\n\nUSAGE: $(basename $0) [-h |--help] <[--force] domain1 domain2...>\n"
fi