Skip to content

Commit

Permalink
Improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
flobernd committed Nov 18, 2024
1 parent 484d099 commit ed5b345
Showing 1 changed file with 53 additions and 46 deletions.
99 changes: 53 additions & 46 deletions minecraft-ftb/data/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,61 @@
set -o pipefail
set -e

function check_environment() {
mandatory=(
echoerr() {
echo "ERROR: $@" 1>&2;
}

check_environment() {
local mandatory=(
"FTB_MODPACK_ID"
)

missing=false
local missing=false
for value in "${mandatory[@]}"
do
if [ -z "${!value}" ]; then
missing=true
echo "ERROR: Missing mandatory environment variable: '$value'"
echoerr "Missing mandatory environment variable: '${value}'"
fi
done

if [ "$missing" = true ]; then
exit 1
if [ "${missing}" = true ]; then
return 1
fi
}

function check_tty() {
check_tty() {
# For some reason, the server process does not shut down gracefully, if no TTY is present ...

if [ ! -t 0 ] ; then
echo "ERROR: The server process requires a TTY. Please pass the '--tty' switch (Docker) or use 'tty: true' (Docker Compose)."
exit 1
echoerr "The server process requires a TTY. Please pass the '--tty' switch (Docker) or use 'tty: true' (Docker Compose)."
return 1
fi
}

# $1 = modpack id
# rt = modpack info JSON payload
function fetch_modpack_info() {
response=$(curl --fail --connect-timeout 30 --max-time 30 "https://api.modpacks.ch/public/modpack/$1")

if [ $(echo "${response}" | jq -r '.status') != "success" ]; then
echo "ERROR: Failed to fetch modpack info. Please check if the modpack id [$1] is correct."
echo "ERROR: $(echo "${response}" | jq -r '.message')"
exit 1
fetch_modpack_info() {
local response
response=$(curl --fail --connect-timeout 30 --max-time 30 --no-progress-meter "https://api.modpacks.ch/public/modpack/$1") || exit $?

if [ -z "${response}" ] || [ $(echo "${response}" | jq -r '.status') != "success" ]; then
echoerr "Failed to fetch modpack info. Please check if the modpack id [$1] is correct."
echoerr "$(echo "${response}" | jq -r '.message')"
return 1
fi

echo "${response}"
}

# $1 = modpack info JSON payload
# rt = latest modpack version id
function query_latest_version_id() {
result=$(echo "$1" | jq -r '[.versions | sort_by(.updated) | reverse | .[] | select(.type == "Release" and .private == false) | .id][0]')
query_latest_version_id() {
local result=$(echo "$1" | jq -r '[.versions | sort_by(.updated) | reverse | .[] | select(.type == "Release" and .private == false) | .id][0]')

if [ -z "${result}" ]; then
echo "ERROR: The selected modpack does not have a public release."
exit 1
echoerr "The selected modpack does not have a public release."
return 1
fi

echo "${result}"
Expand All @@ -61,34 +66,36 @@ function query_latest_version_id() {
# $1 = modpack info JSON payload
# $2 = modpack version id
# rt = modpack version info JSON payload
function query_version_info() {
result=$(echo "$1" | jq -r ".versions[] | select(.id == $2)")
query_version_info() {
local result=$(echo "$1" | jq -r ".versions[] | select(.id == $2)")

if [ -z "${result}" ]; then
echo "ERROR: Failed to query version info. Please check if the modpack version id [$2] is correct."
exit 1
echoerr "Failed to query version info. Please check if the modpack version id [$2] is correct."
return 1
fi

echo "${result}"
}

# $1 = modpack id
# $2 = modpack version id
function get_and_run_installer() {
pack_url="https://api.modpacks.ch/public/modpack/${1}/${2}/server/linux"
pack_installer="serverinstall_${1}_${2}"
get_and_run_installer() {
set -e

local pack_url="https://api.modpacks.ch/public/modpack/${1}/${2}/server/linux"
local pack_installer="/var/lib/minecraft/serverinstall_${1}_${2}"

# Adjust permissions for 'minecraft' directory
chown -R minecraft:minecraft /var/lib/minecraft
chmod 0700 /var/lib/minecraft

# Download the installer
curl --fail --connect-timeout 30 --max-time 30 -o "$pack_installer" "$pack_url"
chmod +x "$pack_installer"
curl --fail --connect-timeout 30 --max-time 30 --no-progress-meter -o "${pack_installer}" "${pack_url}"
chmod +x "${pack_installer}"

# Install- or update the modpack
"./$pack_installer" --auto
rm "$pack_installer"
"${pack_installer}" --auto
rm "${pack_installer}"

# Patch start script
patch_start_script
Expand All @@ -97,7 +104,7 @@ function get_and_run_installer() {
chown -R minecraft:minecraft /var/lib/minecraft
}

function patch_start_script() {
patch_start_script() {
# We have to make sure the `start.sh` script uses `exec` to launch the server. SIGINT and
# other signals would not be forwarded to the Java process otherwise.

Expand All @@ -116,9 +123,9 @@ function patch_start_script() {
done < start.sh

if [ ! success ]; then
echo "ERROR: Failed to patch 'start.sh' script."
echo "ERROR: Please open an issue here: https://github.com/flobernd/docker-minecraft-ftb"
exit 1
echoerr "Failed to patch 'start.sh' script."
echoerr "Please open an issue here: https://github.com/flobernd/docker-minecraft-ftb"
return 1
fi

printf "$output" > start.sh
Expand All @@ -140,27 +147,27 @@ if [ "$1" = "/var/lib/minecraft/start.sh" ]; then
local_version_id=$(jq '.id' version.json)

if [ -z "${local_pack_id}" ] || [ -z "${local_version_id}" ]; then
echo "ERROR: A modpack is already installed, but the 'version.json' could not be parsed."
echoerr "A modpack is already installed, but the 'version.json' could not be parsed."
exit 1
fi

if [ "${local_pack_id}" -ne "${target_pack_id}" ]; then
echo "ERROR: A modpack is already installed, but the modpack id [${local_pack_id}] does not match the configured modpack id [${target_pack_id}]."
echoerr "A modpack is already installed, but the modpack id [${local_pack_id}] does not match the configured modpack id [${target_pack_id}]."
exit 1
fi
fi

# Fetch modpack info

modpack_info=$(fetch_modpack_info "${target_pack_id}") || echo "${modpack_info}" && exit 1
modpack_info=$(fetch_modpack_info "${target_pack_id}")
modpack_name=$(echo "${modpack_info}" | jq -r '.name')

echo "Selected modpack '${modpack_name}' [${target_pack_id}]"

# Query latest version

latest_version_id=$(query_latest_version_id "${modpack_info}") || echo "${latest_version_id}" && exit 1
latest_version_info=$(query_version_info "${modpack_info}" "${latest_version_id}") || echo "${target_version_info}" && exit 1
latest_version_id=$(query_latest_version_id "${modpack_info}")
latest_version_info=$(query_version_info "${modpack_info}" "${latest_version_id}")
latest_version_name=$(echo "${latest_version_info}" | jq -r '.name')

# Determine target version
Expand All @@ -173,7 +180,7 @@ if [ "$1" = "/var/lib/minecraft/start.sh" ]; then
fi
fi

target_version_info=$(query_version_info "${modpack_info}" "${target_version_id}") || echo "${target_version_info}" && exit 1
target_version_info=$(query_version_info "${modpack_info}" "${target_version_id}")
target_version_name=$(echo "${target_version_info}" | jq -r '.name')

# Install modpack
Expand All @@ -182,8 +189,8 @@ if [ "$1" = "/var/lib/minecraft/start.sh" ]; then
echo "Installing modpack version '${target_version_name}' [${target_version_id}]"

if [ "${FORCE_REINSTALL}" != 1 ] && [ $(ls -A . | wc -l) -ne 0 ]; then
echo "ERROR: The destination directory is not empty. Installing the modpack could lead to data loss."
echo "ERROR: To continue, set the 'FORCE_REINSTALL' environment variable to '1' and retry."
echoerr "The destination directory is not empty. Installing the modpack could lead to data loss."
echoerr "To continue, set the 'FORCE_REINSTALL' environment variable to '1' and retry."
exit 1
fi

Expand All @@ -194,14 +201,14 @@ if [ "$1" = "/var/lib/minecraft/start.sh" ]; then

# Query local version

local_version_info=$(query_version_info "${modpack_info}" "${local_version_id}") || echo "${target_version_info}" && exit 1
local_version_info=$(query_version_info "${modpack_info}" "${local_version_id}")
local_version_name=$(echo "${local_version_info}" | jq -r '.name')

# Prevent modpack downgrade

if [ "${local_version_id}" -gt "${target_version_id}" ]; then
echo "ERROR: Detected downgrade from version '${local_version_name}' [${local_version_id}] to '${target_version_name}' [${target_version_id}]."
echo "ERROR: To continue, set the 'FORCE_REINSTALL' environment variable to '1' and retry."
echoerr "Detected downgrade from version '${local_version_name}' [${local_version_id}] to '${target_version_name}' [${target_version_id}]."
echoerr "To continue, set the 'FORCE_REINSTALL' environment variable to '1' and retry."
exit 1
fi

Expand Down

0 comments on commit ed5b345

Please sign in to comment.