Jelajahi Sumber

fix(backup): include game data kept outside rootdir (#5129)

backup only archived rootdir, so game data kept under the home directory was left out whenever rootdir is not the home directory, as in the Docker images. backup now adds, when outside rootdir and not reached through a symlink in it: savedir and servercfgdir for any game, plus the data folders of Project Zomboid, Don't Starve Together, 7 Days to Die, Craftopia, SCP:SL and Barotrauma. Caches and logs are left out.

The previous-backup exclusion is also matched by its path under rootdir, so a symlinked backup directory is not archived into the next backup, and the exclusion check no longer prints a spurious failure when backup stops a running server.

Fixes #3300
Daniel Gibbs 6 hari lalu
induk
melakukan
41e0930109
1 mengubah file dengan 52 tambahan dan 3 penghapusan
  1. 52 3
      lgsm/modules/command_backup.sh

+ 52 - 3
lgsm/modules/command_backup.sh

@@ -135,8 +135,52 @@ fn_select_compression() {
 	fi
 }
 
+# Game data kept outside rootdir, such as worlds saved under the home directory.
+fn_backup_extradirs() {
+	local candidates=()
+	local covered=() dir dirreal link coveredpath
+	backupextradirs=()
+	if [ "${shortname}" == "bt" ]; then
+		candidates+=("${XDG_DATA_HOME:-${HOME}/.local/share}/Daedalic Entertainment GmbH/Barotrauma")
+	elif [ "${shortname}" == "ct" ]; then
+		candidates+=("${serverfiles}DedicatedServerSave")
+	elif [ "${shortname}" == "dst" ]; then
+		candidates+=("${persistentstorageroot}")
+	elif [ "${shortname}" == "pz" ]; then
+		candidates+=("${HOME}/Zomboid")
+	elif [ "${shortname}" == "scpsl" ]; then
+		candidates+=("${HOME}/.config/SCP Secret Laboratory/config")
+	elif [ "${shortname}" == "sdtd" ]; then
+		candidates+=("${HOME}/.local/share/7DaysToDie/Saves")
+	fi
+	candidates+=("${savedir}" "${servercfgdir}")
+	covered+=("$(readlink -f "${rootdir}")")
+	while IFS= read -r link; do
+		covered+=("$(readlink -f "${link}")")
+	done < <(find "${rootdir}" -maxdepth 2 -type l 2> /dev/null)
+	for dir in "${candidates[@]}"; do
+		if [ -z "${dir}" ] || [ ! -d "${dir}" ]; then
+			continue
+		fi
+		dirreal="$(readlink -f "${dir}")"
+		for coveredpath in "${covered[@]}" "${backupextradirs[@]}"; do
+			if [[ "${dirreal}/" == "${coveredpath}/"* ]]; then
+				continue 2
+			fi
+		done
+		backupextradirs+=("${dirreal}")
+	done
+}
+
 # Compressing files.
 fn_backup_compression() {
+	fn_backup_extradirs
+	backupextras=()
+	for extradir in "${backupextradirs[@]}"; do
+		echo -e "* Including ${extradir}"
+		fn_script_log_info "Including ${extradir}"
+		backupextras+=(-C / "${extradir#/}")
+	done
 
 	fn_print_info "A total of ${rootdirduexbackup} will be compressed."
 	fn_script_log_info "A total of ${rootdirduexbackup} will be compressed: ${backupdir}/${backupname}.${compressext}"
@@ -144,16 +188,21 @@ fn_backup_compression() {
 	fn_script_log_info "Backup ${rootdirduexbackup} ${backupname}.${compressext}, in progress"
 	excludedir=$(fn_backup_relpath)
 
-	if [ ! -d "${excludedir}" ]; then
+	if [ ! -d "${rootdir}/${excludedir}" ]; then
 		fn_print_fail_nl "Problem identifying the previous backup directory for exclusion."
 		fn_script_log_fail "Problem identifying the previous backup directory for exclusion"
 		core_exit.sh
 	fi
 
+	backupexcludes=(--exclude "${excludedir}" --exclude "${lockdir}" --exclude "${tmpdir}")
+	if [[ "${backupdir}" == "${rootdir}/"* ]]; then
+		backupexcludes+=(--exclude "./${backupdir#"${rootdir}"/}")
+	fi
+
 	if [ -n "${compressflag}" ]; then
-		tar ${compressflag} -hcf "${backupdir}/${backupname}.${compressext}" -C "${rootdir}" --exclude "${excludedir}" --exclude "${lockdir}" --exclude "${tmpdir}" ./.
+		tar ${compressflag} -hcf "${backupdir}/${backupname}.${compressext}" "${backupexcludes[@]}" -C "${rootdir}" ./. "${backupextras[@]}"
 	else
-		tar -hcf "${backupdir}/${backupname}.${compressext}" -C "${rootdir}" --exclude "${excludedir}" --exclude "${lockdir}" --exclude "${tmpdir}" ./.
+		tar -hcf "${backupdir}/${backupname}.${compressext}" "${backupexcludes[@]}" -C "${rootdir}" ./. "${backupextras[@]}"
 	fi
 
 	exitcode=$?