feat: add minecraft backup integration
This commit is contained in:
parent
b0650c0425
commit
db0e7799e0
3 changed files with 237 additions and 4 deletions
|
@ -1,11 +1,82 @@
|
||||||
FROM restic/restic:0.9.6
|
FROM alpine AS builder
|
||||||
|
|
||||||
RUN apk update && apk add python3 dcron mariadb-client postgresql-client
|
RUN mkdir -p /opt
|
||||||
|
|
||||||
|
ARG IMAGE_ARCH=amd64
|
||||||
|
|
||||||
|
ARG RCON_CLI_VERSION=1.4.4
|
||||||
|
|
||||||
|
ADD https://github.com/itzg/rcon-cli/releases/download/${RCON_CLI_VERSION}/rcon-cli_${RCON_CLI_VERSION}_linux_${IMAGE_ARCH}.tar.gz /tmp/rcon-cli.tar.gz
|
||||||
|
|
||||||
|
RUN tar x -f /tmp/rcon-cli.tar.gz -C /opt/ && \
|
||||||
|
chmod +x /opt/rcon-cli
|
||||||
|
|
||||||
|
ARG RESTIC_VERSION=0.9.5
|
||||||
|
|
||||||
|
ADD https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/restic_${RESTIC_VERSION}_linux_${IMAGE_ARCH}.bz2 /tmp/restic.bz2
|
||||||
|
|
||||||
|
RUN bunzip2 /tmp/restic.bz2 && \
|
||||||
|
mv /tmp/restic /opt/restic && \
|
||||||
|
chmod +x /opt/restic
|
||||||
|
|
||||||
|
ARG DEMOTER_VERSION=0.1.0
|
||||||
|
|
||||||
|
ADD https://github.com/itzg/entrypoint-demoter/releases/download/${DEMOTER_VERSION}/entrypoint-demoter_${DEMOTER_VERSION}_linux_${IMAGE_ARCH}.tar.gz /tmp/entrypoint-demoter.tar.gz
|
||||||
|
|
||||||
|
RUN tar x -f /tmp/entrypoint-demoter.tar.gz -C /opt/ && \
|
||||||
|
chmod +x /opt/entrypoint-demoter
|
||||||
|
|
||||||
|
ARG RCLONE_VERSION=1.49.5
|
||||||
|
|
||||||
|
ADD https://downloads.rclone.org/v${RCLONE_VERSION}/rclone-v${RCLONE_VERSION}-linux-${IMAGE_ARCH}.zip /tmp/rclone.zip
|
||||||
|
|
||||||
|
RUN mkdir -p /tmp/rclone && \
|
||||||
|
unzip /tmp/rclone.zip -d /tmp/rclone && \
|
||||||
|
mv /tmp/rclone/rclone-v${RCLONE_VERSION}-linux-${IMAGE_ARCH}/rclone /opt/rclone && \
|
||||||
|
chmod +x /opt/rclone
|
||||||
|
|
||||||
|
|
||||||
|
FROM alpine
|
||||||
|
|
||||||
|
RUN apk -U --no-cache add \
|
||||||
|
bash \
|
||||||
|
coreutils \
|
||||||
|
openssh-client \
|
||||||
|
python3 \
|
||||||
|
dcron \
|
||||||
|
mariadb-client \
|
||||||
|
postgresql-client
|
||||||
|
|
||||||
|
COPY --from=builder /opt/rcon-cli /opt/rcon-cli
|
||||||
|
|
||||||
|
RUN ln -s /opt/rcon-cli /usr/bin
|
||||||
|
|
||||||
|
COPY --from=builder /opt/restic /opt/restic
|
||||||
|
|
||||||
|
RUN ln -s /opt/restic /usr/bin
|
||||||
|
|
||||||
|
|
||||||
|
COPY --from=builder /opt/entrypoint-demoter /opt/entrypoint-demoter
|
||||||
|
|
||||||
|
RUN ln -s /opt/entrypoint-demoter /usr/bin
|
||||||
|
|
||||||
|
|
||||||
|
COPY --from=builder /opt/rclone /opt/rclone
|
||||||
|
|
||||||
|
RUN ln -s /opt/rclone /usr/bin
|
||||||
|
|
||||||
|
# install rcb python app
|
||||||
|
|
||||||
ADD . /restic-compose-backup
|
ADD . /restic-compose-backup
|
||||||
WORKDIR /restic-compose-backup
|
WORKDIR /restic-compose-backup
|
||||||
|
|
||||||
RUN pip3 install -U pip setuptools wheel && pip3 install -e .
|
RUN pip3 install -U pip setuptools wheel && pip3 install -e .
|
||||||
ENV XDG_CACHE_HOME=/cache
|
ENV XDG_CACHE_HOME=/cache
|
||||||
|
|
||||||
|
# end install
|
||||||
|
|
||||||
|
ADD backup.sh /backup.sh
|
||||||
|
RUN chmod +x ./backup.sh
|
||||||
|
|
||||||
ENTRYPOINT []
|
ENTRYPOINT []
|
||||||
CMD ["./entrypoint.sh"]
|
CMD ["./entrypoint.sh"]
|
162
src/backup.sh
Normal file
162
src/backup.sh
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ "${DEBUG:-false}" == "true" ]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
|
: "${RCON_HOST:=localhost}"
|
||||||
|
: "${RCON_PORT:=25575}"
|
||||||
|
: "${RCON_PASSWORD:=minecraft}"
|
||||||
|
|
||||||
|
export RCON_HOST
|
||||||
|
export RCON_PORT
|
||||||
|
export RCON_PASSWORD
|
||||||
|
|
||||||
|
###############
|
||||||
|
## common ##
|
||||||
|
## functions ##
|
||||||
|
###############
|
||||||
|
|
||||||
|
is_elem_in_array() {
|
||||||
|
# $1 = element
|
||||||
|
# All remaining arguments are array to search for the element in
|
||||||
|
if [ "$#" -lt 2 ]; then
|
||||||
|
log INTERNALERROR "Wrong number of arguments passed to is_elem_in_array function"
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
local element="${1}"
|
||||||
|
shift
|
||||||
|
local e
|
||||||
|
for e; do
|
||||||
|
if [ "${element}" == "${e}" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
log() {
|
||||||
|
if [ "$#" -lt 1 ]; then
|
||||||
|
log INTERNALERROR "Wrong number of arguments passed to log function"
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
local level="${1}"
|
||||||
|
shift
|
||||||
|
local valid_levels=(
|
||||||
|
"INFO"
|
||||||
|
"WARN"
|
||||||
|
"ERROR"
|
||||||
|
"INTERNALERROR"
|
||||||
|
)
|
||||||
|
if ! is_elem_in_array "${level}" "${valid_levels[@]}"; then
|
||||||
|
log INTERNALERROR "Log level ${level} is not a valid level."
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
(
|
||||||
|
# If any arguments are passed besides log level
|
||||||
|
if [ "$#" -ge 1 ]; then
|
||||||
|
# then use them as log message(s)
|
||||||
|
<<<"${*}" cat -
|
||||||
|
else
|
||||||
|
# otherwise read log messages from standard input
|
||||||
|
cat -
|
||||||
|
fi
|
||||||
|
if [ "${level}" == "INTERNALERROR" ]; then
|
||||||
|
echo "Please report this: https://github.com/itzg/docker-mc-backup/issues"
|
||||||
|
fi
|
||||||
|
) | awk -v level="${level}" '{ printf("%s %s %s\n", strftime("%FT%T%z"), level, $0); fflush(); }'
|
||||||
|
} >&2
|
||||||
|
|
||||||
|
retry() {
|
||||||
|
if [ "$#" -lt 3 ]; then
|
||||||
|
log INTERNALERROR "Wrong number of arguments passed to retry function"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# How many times should we retry?
|
||||||
|
# Value smaller than zero means infinitely
|
||||||
|
local retries="${1}"
|
||||||
|
# Time to sleep between retries
|
||||||
|
local interval="${2}"
|
||||||
|
readonly retries interval
|
||||||
|
shift 2
|
||||||
|
|
||||||
|
if (( retries < 0 )); then
|
||||||
|
local retries_msg="infinite"
|
||||||
|
else
|
||||||
|
local retries_msg="${retries}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local i=-1 # -1 since we will increment it before printing
|
||||||
|
while (( retries >= ++i )) || [ "${retries_msg}" != "${retries}" ]; do
|
||||||
|
# Send SIGINT after 5 minutes. If it doesn't shut down in 30 seconds, kill it.
|
||||||
|
if output="$(timeout --signal=SIGINT --kill-after=30s 5m "${@}" 2>&1 | tr '\n' '\t')"; then
|
||||||
|
log INFO "Command executed successfully ${*}"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log ERROR "Unable to execute ${*} - try ${i}/${retries_msg}. Retrying in ${interval}"
|
||||||
|
if [ -n "${output}" ]; then
|
||||||
|
log ERROR "Failure reason: ${output}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
sleep ${interval}
|
||||||
|
done
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
is_function() {
|
||||||
|
if [ "${#}" -ne 1 ]; then
|
||||||
|
log INTERNALERROR "is_function expects 1 argument, received ${#}"
|
||||||
|
fi
|
||||||
|
name="${1}"
|
||||||
|
[ "$(type -t "${name}")" == "function" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
call_if_function_exists() {
|
||||||
|
if [ "${#}" -lt 1 ]; then
|
||||||
|
log INTERNALERROR "call_if_function_exists expects at least 1 argument, received ${#}"
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
function_name="${1}"
|
||||||
|
if is_function "${function_name}"; then
|
||||||
|
eval "${@}"
|
||||||
|
else
|
||||||
|
log INTERNALERROR "${function_name} is not a valid function!"
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
##########
|
||||||
|
## main ##
|
||||||
|
##########
|
||||||
|
|
||||||
|
|
||||||
|
log INFO "waiting for rcon readiness..."
|
||||||
|
# 20 times, 10 second delay
|
||||||
|
retry 20 10s rcon-cli save-on
|
||||||
|
|
||||||
|
|
||||||
|
if retry 5 10s rcon-cli save-off; then
|
||||||
|
# No matter what we were doing, from now on if the script crashes
|
||||||
|
# or gets shut down, we want to make sure saving is on
|
||||||
|
trap 'retry 5 5s rcon-cli save-on' EXIT
|
||||||
|
|
||||||
|
retry 5 10s rcon-cli save-all
|
||||||
|
retry 5 10s sync
|
||||||
|
|
||||||
|
rcb backup
|
||||||
|
|
||||||
|
retry 20 10s rcon-cli save-on
|
||||||
|
# Remove our exit trap now
|
||||||
|
trap EXIT
|
||||||
|
else
|
||||||
|
log ERROR "Unable to turn saving off. Is the server running?"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( PRUNE_BACKUPS_DAYS > 0 )); then
|
||||||
|
rcb cleanup
|
||||||
|
fi
|
|
@ -1,2 +1,2 @@
|
||||||
10 2 * * * source /env.sh && rcb backup > /proc/1/fd/1
|
10 2 * * * source /env.sh && /backup.sh > /proc/1/fd/1
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue