-
Notifications
You must be signed in to change notification settings - Fork 276
/
valheim-backup
executable file
·162 lines (138 loc) · 5.14 KB
/
valheim-backup
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
159
160
161
162
#!/bin/bash
# valheim-backups runs permanently if BACKUPS=true
# and creates backups of the /config/worlds_local directory.
# Include defaults
. /usr/local/etc/valheim/defaults
. /usr/local/etc/valheim/common
# Remove trailing slash if any
BACKUPS_DIRECTORY=${BACKUPS_DIRECTORY%/}
pidfile=$valheim_backup_pidfile
next_backup=$(date +%s)
run=true
main() {
local last_activity
last_activity=$(date +%s)
if (set -o noclobber; echo $$ > "$pidfile") 2> /dev/null; then
trap backup_now SIGHUP
trap shutdown SIGINT SIGTERM
trap 'error_handler $? $LINENO $BASH_LINENO "$BASH_COMMAND" $(printf "::%s" ${FUNCNAME[@]}); trap - ERR' ERR
cd /config || fatal "Could not cd /config"
while [ $run = true ]; do
if [ "$BACKUPS_IF_IDLE" = true ] || [ "$(date +%s)" -le $((last_activity+BACKUPS_IDLE_GRACE_PERIOD)) ]; then
backup
flush_old
else
debug "Not running backup as there has been no server activity since $(date -d @"$last_activity")"
fi
next_backup=$(($(date +%s)+BACKUPS_INTERVAL))
while [ $run = true ] && [ "$(date +%s)" -lt $next_backup ]; do
sleep 20
if [ "$BACKUPS_IF_IDLE" = false ] && ! server_is_idle; then
last_activity=$(date +%s)
fi
done
done
else
info "Found existing pid file - checking process"
check_lock "$pidfile"
fi
}
backup() {
local backup_file
local WORLDS_DIR
if [ -d "$worlds_dir" ]; then
WORLDS_DIR=$worlds_dir
elif [ -d "$old_worlds_dir" ]; then
WORLDS_DIR=$old_worlds_dir
else
info "No worlds to backup"
return
fi
mkdir -p "$BACKUPS_DIRECTORY"
chmod "$BACKUPS_DIRECTORY_PERMISSIONS" "$BACKUPS_DIRECTORY"
if [ "${BACKUPS_ZIP}" = true ]; then
backup_file="$BACKUPS_DIRECTORY/worlds-$(date +%Y%m%d-%H%M%S).zip"
pre_backup_hook "$backup_file"
info "Backing up Valheim server worlds to $backup_file"
zip -r "$backup_file" "$WORLDS_DIR/"
chmod "$BACKUPS_FILE_PERMISSIONS" "$backup_file"
post_backup_hook "$backup_file"
else
local world_file
local backup_suffix
backup_suffix=$(date +%Y%m%d-%H%M%S)
for extension in {db,fwl,db.old,fwl.old}; do
world_file="$WORLDS_DIR/$WORLD_NAME.$extension"
if [ ! -f "$world_file" ]; then
debug "World file $world_file not found - skipping"
continue
fi
backup_file="$BACKUPS_DIRECTORY/AUTOBACKUP-${WORLD_NAME}-$backup_suffix.$extension"
pre_backup_hook "$backup_file"
info "Backing up Valheim server world file $world_file to $backup_file"
cp -v "$world_file" "$backup_file"
chmod "$BACKUPS_FILE_PERMISSIONS" "$backup_file"
post_backup_hook "$backup_file"
done
fi
}
pre_backup_hook() {
local backup_file
local pre_hook_cmd
if [ -n "$PRE_BACKUP_HOOK" ]; then
backup_file=$1
pre_hook_cmd=${PRE_BACKUP_HOOK//@BACKUP_FILE@/$backup_file}
info "Running pre backup hook: $pre_hook_cmd"
eval "$pre_hook_cmd"
fi
}
post_backup_hook() {
local backup_file
local post_hook_cmd
if [ -n "$POST_BACKUP_HOOK" ]; then
backup_file=$1
post_hook_cmd=${POST_BACKUP_HOOK//@BACKUP_FILE@/$backup_file}
info "Running post backup hook: $post_hook_cmd"
eval "$post_hook_cmd"
fi
}
flush_old() {
if [ ! -d "$BACKUPS_DIRECTORY" ]; then
debug "No old backups to remove"
return
fi
if [ "$BACKUPS_MAX_COUNT" -gt 0 ]; then
info "Removing all but the newest $BACKUPS_MAX_COUNT backups"
if [ "${BACKUPS_ZIP}" = true ]; then
find "$BACKUPS_DIRECTORY" -type f -name "worlds-*.zip" -printf '%T@ %p\0' | sort -z -n -r | cut -z -s -d " " -f "2-" | tail -z -n +$((BACKUPS_MAX_COUNT+1)) | xargs -0 rm -fv -- 2>/dev/null
else
for extension in {db,fwl,db.old,fwl.old}; do
find "$BACKUPS_DIRECTORY" -type f -name "AUTOBACKUP-${WORLD_NAME}-*.${extension}" -printf '%T@ %p\0' | sort -z -n -r | cut -z -s -d " " -f "2-" | tail -z -n +$((BACKUPS_MAX_COUNT+1)) | xargs -0 rm -v -- 2>/dev/null
done
fi
fi
info "Removing backups older than $BACKUPS_MAX_AGE days"
if [ "${BACKUPS_ZIP}" = true ]; then
find "$BACKUPS_DIRECTORY" -type f -mmin "+$((BACKUPS_MAX_AGE*60*24))" -name "worlds-*.zip" -print -exec rm -f "{}" \;
else
for extension in {db,fwl,db.old,fwl.old}; do
find "$BACKUPS_DIRECTORY" -type f -mmin "+$((BACKUPS_MAX_AGE*60*24))" -name "AUTOBACKUP-${WORLD_NAME}-*.${extension}" -print -exec rm -f "{}" \;
done
fi
}
# This is a signal handler registered to SIGHUP
backup_now() {
debug "Received signal to backup world"
next_backup=0
}
shutdown() {
debug "Received signal to shut down valheim-backup"
clear_lock "$pidfile"
run=false
}
if [ "$BACKUPS" = true ]; then
main
else
info "Backups have been turned off by env BACKUPS=$BACKUPS"
supervisorctl stop valheim-backup
fi