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 MC_PATH="/example/servers/minecraft_spigot"
39 WORLDS_DIR="$MC_PATH/worlds"
40 PLUGINS_DIR="$MC_PATH/plugins"
41 LOG_FILE="$MC_PATH/backup.log"
42 LOCK_FILE="$MC_PATH/backup.lockfile"
43
44
45 BACKUP_PATH="/example/backups"
46
47
48 KEEP_HOURLY="1"
49 KEEP_DAILY="15"
50 KEEP_MONTHLY="4"
51
52
53 DATED_DIRS=$(date +"%Y/%B/%d/%H:%M")
54 TIMESTAMP() { date +"%D %T"; }
55
56
57
58 SFTP_ARGS=(-P 32 -i /path/to/key user@127.0.0.1)
59 SSH_ARGS=(-p 32 -i /path/to/key user@127.0.0.1)
60
61
62
63
64
65
66 backup_hourly()
67 {
68
69 echo "$(TIMESTAMP) Starting hourly backup..." >> "$LOG_FILE"
70
71 check_lock
72
73 echo "$(TIMESTAMP) Creating backup directory $BACKUP_PATH/$DATED_DIRS ..." >> "$LOG_FILE"
74 ssh "${SSH_ARGS[@]}" "mkdir -p $BACKUP_PATH/$DATED_DIRS" > /dev/null 2>> "$LOG_FILE"
75
76 echo "$(TIMESTAMP) Backing up files..." >> "$LOG_FILE"
77 {
78 sftp "${SFTP_ARGS[@]}" <<EOF
79 put -R "$WORLDS_DIR"/world "$BACKUP_PATH/$DATED_DIRS"
80 put "$PLUGINS_DIR"/TPPets/tppets.db "$BACKUP_PATH/$DATED_DIRS"
81 put -R "$PLUGINS_DIR"/PerWorldInventory/data "$BACKUP_PATH/$DATED_DIRS"
82 exit
83 EOF
84 } > /dev/null 2>> "$LOG_FILE"
85 echo "$(TIMESTAMP) Hourly backup complete." >> "$LOG_FILE"
86 }
87
88 backup_daily()
89 {
90
91 echo "$(TIMESTAMP) Starting daily backup..." >> "$LOG_FILE"
92
93 echo "$(TIMESTAMP) Creating backup directory $BACKUP_PATH/$DATED_DIRS ..." >> "$LOG_FILE"
94 ssh "${SSH_ARGS[@]}" "mkdir -p $BACKUP_PATH/$DATED_DIRS" > /dev/null 2>> "$LOG_FILE"
95
96 echo "$(TIMESTAMP) Backing up files..." >> "$LOG_FILE"
97 {
98 sftp "${SFTP_ARGS[@]}" <<EOF
99 put -R "$WORLDS_DIR"/world_nether "$BACKUP_PATH/$DATED_DIRS"
100 put -R "$WORLDS_DIR"/world_the_end "$BACKUP_PATH/$DATED_DIRS"
101 exit
102 EOF
103 } > /dev/null 2>> "$LOG_FILE"
104 echo "$(TIMESTAMP) Daily backup complete." >> "$LOG_FILE"
105 }
106
107 backup_weekly()
108 {
109
110 echo "$(TIMESTAMP) Starting weekly backup..." >> "$LOG_FILE"
111
112 echo "$(TIMESTAMP) Creating backup directory $BACKUP_PATH/$DATED_DIRS ..." >> "$LOG_FILE"
113 ssh "${SSH_ARGS[@]}" "mkdir -p $BACKUP_PATH/$DATED_DIRS" > /dev/null 2>> "$LOG_FILE"
114
115 echo "$(TIMESTAMP) Backing up files..." >> "$LOG_FILE"
116 {
117 sftp "${SFTP_ARGS[@]}" <<EOF
118 put -R "$WORLDS_DIR"/world_creative "$BACKUP_PATH/$DATED_DIRS"
119 put -R "$WORLDS_DIR"/world_superflat "$BACKUP_PATH/$DATED_DIRS"
120 exit
121 EOF
122 } > /dev/null 2>> "$LOG_FILE"
123 echo "$(TIMESTAMP) weekly backup complete." >> "$LOG_FILE"
124 }
125
126
127
128
129
130 clean_hourly()
131 {
132
133
134
135
136
137 CLEANUP_FOLDER=$(date --date="$KEEP_HOURLY days ago" +%Y/%B/%d)
138
139 echo "$(TIMESTAMP) Beginning cleanup of old hourly backups..." >> "$LOG_FILE"
140 ssh "${SSH_ARGS[@]}" "rm -rfv $BACKUP_PATH/$CLEANUP_FOLDER/{01..23}:00" > /dev/null 2>> "$LOG_FILE"
141 echo "$(TIMESTAMP) Hourly cleanup complete." >> "$LOG_FILE"
142 }
143
144 clean_daily()
145 {
146
147
148
149
150 CLEANUP_FOLDER=$(date --date="$KEEP_DAILY days ago" +%Y/%B)
151 CLEANUP_DAY=$(date --date="$KEEP_DAILY days ago" +%d)
152
153 echo "$(TIMESTAMP) Beginning cleanup of old daily backups..." >> "$LOG_FILE"
154 if [ "$CLEANUP_DAY" != "01" ]; then
155 echo "$(TIMESTAMP) Cleaning $CLEANUP_FOLDER/$CLEANUP_DAY ..." >> "$LOG_FILE"
156 ssh "${SSH_ARGS[@]}" "rm -rfv $BACKUP_PATH/$CLEANUP_FOLDER/$CLEANUP_DAY" > /dev/null 2>> "$LOG_FILE"
157 else
158 echo "$(TIMESTAMP) Leaving backup from the first of the month." >> "$LOG_FILE"
159 fi
160 echo "$(TIMESTAMP) Daily cleanup complete." >> "$LOG_FILE"
161
162 }
163
164 clean_monthly()
165 {
166
167
168
169
170
171 CLEANUP_FOLDER=$(date --date="$KEEP_MONTHLY months ago" +%Y/%B)
172
173 echo "$(TIMESTAMP) Beginning cleanup of old monthly backups..." >> "$LOG_FILE"
174 echo "$(TIMESTAMP) Cleaning $CLEANUP_FOLDER ..." >> "$LOG_FILE"
175 ssh "${SSH_ARGS[@]}" "rm -rfv $BACKUP_PATH/$CLEANUP_FOLDER" > /dev/null 2>> "$LOG_FILE"
176 echo "$(TIMESTAMP) Monthly cleanup complete." >> "$LOG_FILE"
177 }
178
179
180
181
182
183
184 show_help()
185 {
186 echo "A backup script for the tilde Minecraft server"
187 echo ""
188 echo "Backs files up to a remote server. Uses ssh and sftp"
189 echo "Designed to be run as a cronjob on the local server"
190 echo ""
191 echo "Usage: tildecraftBAK.sh [command] [option]"
192 echo ""
193 echo " -b <hourly/daily/weekly> Run the specified backup"
194 echo " -c <hourly/daily/monthly> Run the specified cleanup"
195 echo ""
196 echo "An example crontab that utilizes all functions:"
197 echo ""
198 echo "@hourly tildecraftBAK.sh -b hourly; tildecraftBAK.sh -c hourly"
199 echo "@daily tildecraftBAK.sh -b daily; tildecraftBAK.sh -c daily"
200 echo "@weekly tildecraftBAK.sh -b weekly"
201 echo "@monthly tildecraftBAK.sh -c monthly"
202 exit 0
203 }
204
205
206 which_backup()
207 {
208 case "$1" in
209 hourly)
210 backup_hourly
211 ;;
212 daily)
213 backup_daily
214 ;;
215 weekly)
216 backup_weekly
217 ;;
218 *)
219 show_help
220 ;;
221 esac
222 }
223
224
225 which_cleanup()
226 {
227 case "$1" in
228 hourly)
229 clean_hourly
230 ;;
231 daily)
232 clean_daily
233 ;;
234 monthly)
235 clean_monthly
236 ;;
237 *)
238 show_help
239 ;;
240 esac
241 }
242
243 check_lock()
244 {
245
246
247
248 exec 9>"$LOCK_FILE"
249 if ! flock -n 9; then
250 echo "$(TIMESTAMP) Another instance of the backup is running. Aborting." >> "$LOG_FILE"
251 exit 1
252 fi
253 }
254
255 check_sanity()
256 {
257
258 if [ ! -x "$(command -v ssh)" ] || [ ! -x "$(command -v sftp)" ]; then
259 echo "This script requires ssh and sftp!"
260 exit 1
261 elif [ ! -d "$MC_PATH" ]; then
262 echo "Directory not found: $MC_PATH"
263 exit 1
264 elif [ ! -d "$WORLDS_DIR" ]; then
265 echo "Directory not found: $WORLDS_DIR"
266 exit 1
267 elif [ ! -d "$PLUGINS_DIR" ]; then
268 echo "Directory not found: $PLUGINS_DIR"
269 exit 1
270 fi
271 }
272
273
274
275
276
277 if [ "$#" -eq 0 ]; then
278
279 show_help
280 exit 0
281 fi
282
283
284 while getopts :b:c: option
285 do
286 case "$option" in
287 b)
288 check_sanity
289 which_backup "$OPTARG"
290 ;;
291 c)
292 check_sanity
293 which_cleanup "$OPTARG"
294 ;;
295 *|\?)
296 echo "Invalid option"
297 echo ""
298 show_help
299 ;;
300 esac
301 done