diff --git a/0.17/Dockerfile b/0.17/Dockerfile index cfd4535..67938af 100644 --- a/0.17/Dockerfile +++ b/0.17/Dockerfile @@ -20,8 +20,7 @@ ENV PORT=34197 \ PGID="$PGID" RUN mkdir -p /opt /factorio && \ - apk add --update --no-cache pwgen su-exec binutils gettext libintl shadow && \ - apk add --update --no-cache --virtual .build-deps curl && \ + apk add --update --no-cache pwgen su-exec binutils gettext libintl shadow curl jq && \ curl -sSL "https://www.factorio.com/get-download/$VERSION/headless/linux64" \ -o /tmp/factorio_headless_x64_$VERSION.tar.xz && \ echo "$SHA1 /tmp/factorio_headless_x64_$VERSION.tar.xz" | sha1sum -c && \ @@ -32,7 +31,6 @@ RUN mkdir -p /opt /factorio && \ ln -s "$MODS" /opt/factorio/mods && \ ln -s "$SCENARIOS" /opt/factorio/scenarios && \ ln -s "$SCRIPTOUTPUT" /opt/factorio/script-output && \ - apk del .build-deps && \ addgroup -g "$PGID" -S "$GROUP" && \ adduser -u "$PUID" -G "$GROUP" -s /bin/sh -SDH "$USER" && \ chown -R "$USER":"$GROUP" /opt/factorio /factorio diff --git a/0.17/docker-compose.yml b/0.17/docker-compose.yml index 74622c3..5aaeb6c 100644 --- a/0.17/docker-compose.yml +++ b/0.17/docker-compose.yml @@ -10,3 +10,6 @@ services: # environment: # - PUID=1000 # - PGID=1000 +# - UPDATE_MODS_ON_START=true +# - USERNAME=FactorioUsername +# - TOKEN=FactorioToken diff --git a/0.17/files/docker-entrypoint.sh b/0.17/files/docker-entrypoint.sh index aaf8817..a021fe2 100755 --- a/0.17/files/docker-entrypoint.sh +++ b/0.17/files/docker-entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/sh -x +#!/bin/bash -x set -euo pipefail id @@ -35,6 +35,10 @@ if [ "$NRTMPSAVES" -gt 0 ]; then rm -f "$SAVES"/*.tmp.zip fi +if [[ $UPDATE_MODS_ON_START ]]; then + ./docker-update-mods.sh +fi + if [ "$(id -u)" = '0' ]; then # Update the User and Group ID based on the PUID/PGID variables usermod -o -u "$PUID" factorio diff --git a/0.17/files/docker-update-mods.sh b/0.17/files/docker-update-mods.sh new file mode 100644 index 0000000..f4e1675 --- /dev/null +++ b/0.17/files/docker-update-mods.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +if [[ -f /run/secrets/username ]]; then + USERNAME=$(cat /run/secrets/username) +fi + +if [[ -f /run/secrets/username ]]; then + TOKEN=$(cat /run/secrets/token) +fi + +if [[ -z $TOKEN ]]; then + set -- "$(jq -j ".username, \" \", .token" "$CONFIG/server-settings.json")" + USERNAME=$1 + TOKEN=$2 +fi + +./update-mods.sh "$VERSION" "$MODS" "$USERNAME" "$TOKEN" diff --git a/0.17/files/update-mods.sh b/0.17/files/update-mods.sh new file mode 100644 index 0000000..41d7299 --- /dev/null +++ b/0.17/files/update-mods.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +FACTORIO_VERSION=$1 +MOD_DIR=$2 +USERNAME=$3 +TOKEN=$4 + +MOD_BASE_URL="https://mods.factorio.com" + +print_step() +{ + echo "$1" +} + +print_success() +{ + echo "$1" +} + +print_failure() +{ + echo "$1" +} + +update_mod() +{ + MOD_NAME="$1" + + print_step "Checking for update of mod $MOD_NAME..." + + MOD_INFO_URL="$MOD_BASE_URL/api/mods/$MOD_NAME" + MOD_INFO_JSON=$(curl --silent "$MOD_INFO_URL") + + MOD_INFO=$(echo "$MOD_INFO_JSON" | jq -j --arg version "$FACTORIO_VERSION" ".releases|reverse|map(select(.info_json.factorio_version as \$mod_version | \$version | startswith(\$mod_version)))[0]|.file_name, \";\", .download_url, \";\", .sha1") + + MOD_FILENAME=$(echo "$MOD_INFO" | cut -f1 -d";") + MOD_URL=$(echo "$MOD_INFO" | cut -f2 -d";") + MOD_SHA1=$(echo "$MOD_INFO" | cut -f3 -d";") + + if [[ -z $MOD_URL ]]; then + return 1 + fi + + if [[ $MOD_FILENAME == null ]]; then + print_failure " Not compatible with version" + return 1 + fi + + if [[ -f $MOD_DIR/$MOD_FILENAME ]]; then + print_success " Already up-to-date." + return 0 + fi + + print_step "Downloading..." + FULL_URL="$MOD_BASE_URL$MOD_URL?username=$USERNAME&token=$TOKEN" + HTTP_STATUS=$(curl --silent -L -w "%{http_code}" -o "$MOD_DIR/$MOD_FILENAME" "$FULL_URL") + + if [[ $HTTP_STATUS != 200 ]]; then + print_failure " Download failed: Code $HTTP_STATUS." + rm "$MOD_DIR/$MOD_FILENAME" + return 1 + fi + + if [[ ! -f $MOD_DIR/$MOD_FILENAME ]]; then + print_failure " Downloaded file missing!" + return 1 + fi + + set -- "$(sha1sum "$MOD_DIR/$MOD_FILENAME")" + if [[ $1 != "$MOD_SHA1" ]]; then + print_failure " SHA1 mismatch!" + rm "$MOD_DIR/$MOD_FILENAME" + return 1 + fi + + print_success " Download complete." + + for file in "$MOD_DIR/${MOD_NAME}_"*".zip"; do # wildcard does usually not work in quotes: https://unix.stackexchange.com/a/67761 + if [[ $file != $MOD_DIR/$MOD_FILENAME ]]; then + print_success " Deleting old version: $file" + rm "$file" + fi + done + + return 0 +} + +if [[ -f $MOD_DIR/mod-list.json ]]; then + jq -r ".mods|map(select(.enabled))|.[].name" "$MOD_DIR/mod-list.json" | while read -r mod; do + if [[ $mod != base ]]; then + update_mod "$mod" + fi + done +fi diff --git a/README.md b/README.md index 45df05f..7dabf04 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,8 @@ To generate a new map stop the server, delete all of the saves and restart the s Copy mods into the mods folder and restart the server. +As of 0.17 a new environment variable was added ``UPDATE_MODS_ON_START`` which if set to ``true`` will cause the mods get to updated on server start. If set a valid [Factorio Username and Token](https://www.factorio.com/profile) must be supplied or else the server will not start. They can either be set as docker secrets, environment variables, or pulled from the server-settings.json file. + ## Scenarios