From 8a50adce5c5efa208b4ac093c41f501bf02e0ac9 Mon Sep 17 00:00:00 2001 From: Nicolas Chan Date: Mon, 3 May 2021 13:31:02 -0700 Subject: [PATCH 1/7] Add restic to CI --- .github/workflows/ci.yml | 9 +------ .github/workflows/docker.yml | 50 ++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9310640..f08015b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: submodules: 'recursive' - name: Install kcov and shellcheck - run: sudo apt-get install -y kcov shellcheck + run: sudo apt-get install -y kcov shellcheck restic - name: Run tests run: test/test.sh @@ -39,10 +39,3 @@ jobs: - name: shellcheck run: shellcheck backup.sh - - - name: Build the Docker image - run: | - echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin - docker build . --file Dockerfile --tag ghcr.io/nicolaschan/minecraft-backup:$GITHUB_SHA --tag ghcr.io/nicolaschan/minecraft-backup:latest - docker push ghcr.io/nicolaschan/minecraft-backup:$GITHUB_SHA - docker push ghcr.io/nicolaschan/minecraft-backup:latest diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..16844bb --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,50 @@ +# This is a basic workflow to help you get started with Actions + +name: Docker + +# Controls when the action will run. +on: + push: + branches: + - master + pull_request: + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + with: + submodules: 'recursive' + + - name: Install kcov and shellcheck + run: sudo apt-get install -y kcov shellcheck restic + + - name: Run tests + run: test/test.sh + + - name: Run coverage + run: kcov --include-pattern=backup.sh "$(pwd)"/coverage test/test.sh + + - name: Codecov + uses: codecov/codecov-action@v1.2.1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + file: ./coverage/test.sh/cov.xml + + - name: shellcheck + run: shellcheck backup.sh + + - name: Build the Docker image + run: | + echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin + docker build . --file Dockerfile --tag ghcr.io/nicolaschan/minecraft-backup:$GITHUB_SHA --tag ghcr.io/nicolaschan/minecraft-backup:latest + docker push ghcr.io/nicolaschan/minecraft-backup:$GITHUB_SHA + docker push ghcr.io/nicolaschan/minecraft-backup:latest From 2c86dae9ae96188e17c4b0c23786418c51fd245c Mon Sep 17 00:00:00 2001 From: Nicolas Chan Date: Mon, 3 May 2021 13:32:44 -0700 Subject: [PATCH 2/7] Handle chmod when file does not exist --- test/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.sh b/test/test.sh index 21179fa..2133afe 100755 --- a/test/test.sh +++ b/test/test.sh @@ -9,7 +9,7 @@ RCON_PORT="8088" RCON_PASSWORD="supersecret" export RESTIC_PASSWORD="restic-pass-secret" setUp () { - chmod -R 755 "$TEST_TMP" + chmod -R 755 "$TEST_TMP" || true rm -rf "$TEST_TMP" mkdir -p "$TEST_TMP/server/world" mkdir -p "$TEST_TMP/backups" From 5fca26542d4685527ad9a0fea5db4213ffcdf3cf Mon Sep 17 00:00:00 2001 From: Nicolas Chan Date: Mon, 3 May 2021 14:13:08 -0700 Subject: [PATCH 3/7] Check for snapshot instead of warning message --- test/test.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/test.sh b/test/test.sh index 2133afe..070d52f 100755 --- a/test/test.sh +++ b/test/test.sh @@ -84,7 +84,8 @@ test-restic-incomplete-snapshot () { chmod 000 "$TEST_TMP/server/world/file1.txt" TIMESTAMP="$(date +%F_%H-%M-%S --date="2021-01-01")" OUTPUT="$(./backup.sh -i "$TEST_TMP/server/world" -r "$TEST_TMP/backups-restic" -s "$SCREEN_TMP" -f "$TIMESTAMP")" - assertContains "$OUTPUT" "Incomplete snapshot taken" + assertEquals 1 "$(restic list snapshots -r "$TEST_TMP/backups-restic" | wc -l)" + # assertContains "$OUTPUT" "Incomplete snapshot taken" } test-restic-no-snapshot () { From 81f84d8aa4b366b8c2d39ca7ba2190c904fd8c31 Mon Sep 17 00:00:00 2001 From: Nicolas Chan Date: Mon, 3 May 2021 14:41:44 -0700 Subject: [PATCH 4/7] Update README --- README.md | 18 +++++++++++++++++- backup.sh | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3f1a4bb..c46073a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![codecov](https://codecov.io/gh/nicolaschan/minecraft-backup/branch/master/graph/badge.svg?token=LCbVC4TbYJ)](https://codecov.io/gh/nicolaschan/minecraft-backup) Backup script for Minecraft servers on Linux. -Supports servers running in [screen](https://en.wikipedia.org/wiki/GNU_Screen), [tmux](https://en.wikipedia.org/wiki/Tmux), or with [RCON](https://wiki.vg/RCON) enabled. +Supports servers running in [screen](https://en.wikipedia.org/wiki/GNU_Screen), [tmux](https://en.wikipedia.org/wiki/Tmux), or with [RCON](https://wiki.vg/RCON) enabled. Supports `tar` file or [`restic`](https://restic.net/) backup backends. ## Features - Create backups of your world folder @@ -32,6 +32,18 @@ If using RCON, you will also need to have the [`xxd`](https://linux.die.net/man/ # If running on tmux session 0: ./backup.sh -c -i /home/user/server/world -o /mnt/storage/backups -s 0 -w tmux + +# Using restic (and RCON) +export RESTIC_PASSWORD="restic-pass-secret" # your password here +./backup.sh -c -i /home/user/server/world -r /mnt/storage/backups-restic -s localhost:25575:secret -w rcon + +# Using Docker and RCON +# You will have to set up networking so that this Docker image can access the RCON server +# In this example, the RCON server hostname is `server-host` +docker run \ + -v /home/user/server/world:/mnt/server \ + -v /mnt/storage/backups:/mnt/backups \ + ghcr.io/nicolaschan/minecraft-backup -c -i /mnt/server -o /mnt/backups -s server-host:25575:secret -w rcon ``` This will show chat messages (`-c`) and save a backup of `/home/user/server/world` into `/mnt/storage/backups` using the default thinning deletion policy for old backups. @@ -50,6 +62,7 @@ Command line options: -o Output directory -p Prefix that shows in Minecraft chat (default: Backup) -q Suppress warnings +-r Restic repo name (if using restic) -s Screen name, tmux session name, or hostname:port:password for RCON -v Verbose mode -w Window manager: screen (default), tmux, RCON @@ -74,6 +87,9 @@ tar -xzvf /path/to/backups/2019-04-09_02-15-01.tar.gz Then you can move your restored world (`restored-world` in this case) to your Minecraft server folder and rename it (usually called `world`) so the Minecraft server uses it. +### With `restic` +Use [`restic restore`](https://restic.readthedocs.io/en/latest/050_restore.html) to restore from backup. + ## Why not use `tar` directly? If you use `tar` while the server is running, you will likely get an error like this because Minecraft autosaves the world periodically: ``` diff --git a/backup.sh b/backup.sh index 06bad21..ae5a15a 100755 --- a/backup.sh +++ b/backup.sh @@ -57,9 +57,9 @@ while getopts 'a:cd:e:f:hi:l:m:o:p:qr:s:vw:' FLAG; do echo "-l Compression level (default: 3)" echo "-m Maximum backups to keep, use -1 for unlimited (default: 128)" echo "-o Output directory" - echo "-r Restic repo name (if using restic)" echo "-p Prefix that shows in Minecraft chat (default: Backup)" echo "-q Suppress warnings" + echo "-r Restic repo name (if using restic)" echo "-s Screen name, tmux session name, or hostname:port:password for RCON" echo "-v Verbose mode" echo "-w Window manager: screen (default), tmux, RCON" From ac509153eaa4930e3247fab3ba5312aecdeee7ee Mon Sep 17 00:00:00 2001 From: Nicolas Chan Date: Mon, 3 May 2021 15:04:30 -0700 Subject: [PATCH 5/7] No docker image on pull requests --- .github/workflows/docker.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 16844bb..9a21bf0 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -7,7 +7,6 @@ on: push: branches: - master - pull_request: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: From af04534ac51effb7c0f1df6134f8d57dfd4cec0f Mon Sep 17 00:00:00 2001 From: Nicolas Chan Date: Mon, 3 May 2021 15:18:32 -0700 Subject: [PATCH 6/7] Update restic version --- .github/workflows/ci.yml | 8 +++++++- .github/workflows/docker.yml | 13 +++++++++---- test/test.sh | 2 +- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f08015b..992972d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,13 @@ jobs: submodules: 'recursive' - name: Install kcov and shellcheck - run: sudo apt-get install -y kcov shellcheck restic + run: sudo apt-get install -y kcov shellcheck + + - name: Install restic + run: | + wget https://github.com/restic/restic/releases/download/v0.12.0/restic_0.12.0_linux_amd64.bz2 + bzip2 -d restic_0.12.0_linux_amd64.bz2 + sudo cp restic_0.12.0_linux_amd64 /usr/local/bin/restic - name: Run tests run: test/test.sh diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9a21bf0..7794cbe 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,12 +1,11 @@ # This is a basic workflow to help you get started with Actions -name: Docker +name: CI # Controls when the action will run. on: push: - branches: - - master + pull_request: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -24,7 +23,13 @@ jobs: submodules: 'recursive' - name: Install kcov and shellcheck - run: sudo apt-get install -y kcov shellcheck restic + run: sudo apt-get install -y kcov shellcheck + + - name: Install restic + run: | + wget https://github.com/restic/restic/releases/download/v0.12.0/restic_0.12.0_linux_amd64.bz2 + bzip2 -d restic_0.12.0_linux_amd64.bz2 + sudo cp restic_0.12.0_linux_amd64 /usr/local/bin/restic - name: Run tests run: test/test.sh diff --git a/test/test.sh b/test/test.sh index 070d52f..9f13e4e 100755 --- a/test/test.sh +++ b/test/test.sh @@ -85,7 +85,7 @@ test-restic-incomplete-snapshot () { TIMESTAMP="$(date +%F_%H-%M-%S --date="2021-01-01")" OUTPUT="$(./backup.sh -i "$TEST_TMP/server/world" -r "$TEST_TMP/backups-restic" -s "$SCREEN_TMP" -f "$TIMESTAMP")" assertEquals 1 "$(restic list snapshots -r "$TEST_TMP/backups-restic" | wc -l)" - # assertContains "$OUTPUT" "Incomplete snapshot taken" + assertContains "$OUTPUT" "Incomplete snapshot taken" } test-restic-no-snapshot () { From e05eab3a929b700c5c71eb79cb5ab0ea745201e2 Mon Sep 17 00:00:00 2001 From: Nicolas Chan Date: Mon, 3 May 2021 15:23:13 -0700 Subject: [PATCH 7/7] Mark restic executable --- .github/workflows/ci.yml | 1 + .github/workflows/docker.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 992972d..feea70d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,7 @@ jobs: wget https://github.com/restic/restic/releases/download/v0.12.0/restic_0.12.0_linux_amd64.bz2 bzip2 -d restic_0.12.0_linux_amd64.bz2 sudo cp restic_0.12.0_linux_amd64 /usr/local/bin/restic + sudo chmod +x /usr/local/bin/restic - name: Run tests run: test/test.sh diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 7794cbe..cab6284 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -30,6 +30,7 @@ jobs: wget https://github.com/restic/restic/releases/download/v0.12.0/restic_0.12.0_linux_amd64.bz2 bzip2 -d restic_0.12.0_linux_amd64.bz2 sudo cp restic_0.12.0_linux_amd64 /usr/local/bin/restic + sudo chmod +x /usr/local/bin/restic - name: Run tests run: test/test.sh