mirror of
https://github.com/okxlin/appstore.git
synced 2026-11-13 08:06:29 +00:00
* Update opencloudeu/opencloud-rolling Docker tag to v9.1.0 * Update app version [skip ci] * Fix OpenCloud Traefik routing without Docker socket Serve OpenCloud through a persistent file-provider route and remove Traefik Docker API access. Create the route only when absent so existing dynamic config is preserved, and avoid nested file mounts beneath the read-only dynamic-config bind mount. --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: github-action update-app-version <githubaction@githubaction.com> Co-authored-by: okxlin <61420215+okxlin@users.noreply.github.com>
141 lines
4.2 KiB
Bash
Executable File
141 lines
4.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
|
|
ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}"
|
|
|
|
fail() {
|
|
printf '%s\n' "$1" >&2
|
|
exit 1
|
|
}
|
|
|
|
ensure_no_symlink_components() {
|
|
local path="$1"
|
|
local current="/"
|
|
local part
|
|
local -a components
|
|
|
|
[[ "$path" == /* ]] || fail "Path must be absolute: $path"
|
|
IFS='/' read -r -a components <<< "$path"
|
|
for part in "${components[@]}"; do
|
|
case "$part" in
|
|
"" | .) continue ;;
|
|
..)
|
|
if [[ "$current" == /*/* ]]; then
|
|
current="${current%/*}"
|
|
else
|
|
current="/"
|
|
fi
|
|
;;
|
|
*)
|
|
if [[ "$current" == / ]]; then
|
|
current="/$part"
|
|
else
|
|
current="$current/$part"
|
|
fi
|
|
;;
|
|
esac
|
|
[[ ! -L "$current" ]] || fail "Data path must not contain a symbolic link: $current"
|
|
done
|
|
}
|
|
|
|
read_env_value() {
|
|
local key="$1"
|
|
local value=""
|
|
|
|
if [[ -f "$ENV_FILE" ]]; then
|
|
value="$(grep -E "^${key}=" "$ENV_FILE" | tail -n 1 | cut -d '=' -f 2- || true)"
|
|
fi
|
|
if [[ ${#value} -ge 2 && "${value:0:1}" == '"' && "${value: -1}" == '"' ]]; then
|
|
value="${value:1:${#value}-2}"
|
|
elif [[ ${#value} -ge 2 && "${value:0:1}" == "'" && "${value: -1}" == "'" ]]; then
|
|
value="${value:1:${#value}-2}"
|
|
fi
|
|
printf '%s\n' "$value"
|
|
}
|
|
|
|
if [[ ${APP_DATA_DIR+x} ]]; then
|
|
APP_DATA_DIR_RAW="$APP_DATA_DIR"
|
|
else
|
|
APP_DATA_DIR_RAW="$(read_env_value APP_DATA_DIR)"
|
|
fi
|
|
APP_DATA_DIR_RAW="${APP_DATA_DIR_RAW:-./data}"
|
|
|
|
if [[ ${OC_DOMAIN+x} ]]; then
|
|
OC_DOMAIN_RAW="$OC_DOMAIN"
|
|
else
|
|
OC_DOMAIN_RAW="$(read_env_value OC_DOMAIN)"
|
|
fi
|
|
|
|
[[ -n "$APP_DATA_DIR_RAW" ]] || fail "APP_DATA_DIR must not be empty"
|
|
case "$APP_DATA_DIR_RAW" in
|
|
*$'\n'* | *$'\r'* | *'$'* | *'#'*) fail "APP_DATA_DIR contains unsupported dotenv characters" ;;
|
|
esac
|
|
|
|
case "$APP_DATA_DIR_RAW" in
|
|
/*)
|
|
ensure_no_symlink_components "$APP_DATA_DIR_RAW"
|
|
APP_DATA_DIR_ABS="$(realpath -m -- "$APP_DATA_DIR_RAW")"
|
|
;;
|
|
*)
|
|
ensure_no_symlink_components "${ROOT_DIR}/${APP_DATA_DIR_RAW#./}"
|
|
APP_DATA_DIR_ABS="$(realpath -m -- "${ROOT_DIR}/${APP_DATA_DIR_RAW#./}")"
|
|
case "$APP_DATA_DIR_ABS" in
|
|
"$ROOT_DIR" | "$ROOT_DIR"/*) ;;
|
|
*) fail "Relative APP_DATA_DIR must stay inside the application directory" ;;
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
[[ "$APP_DATA_DIR_ABS" != / ]] || fail "APP_DATA_DIR must not be the filesystem root"
|
|
[[ ! -L "$APP_DATA_DIR_ABS" ]] || fail "APP_DATA_DIR must not be a symbolic link"
|
|
if [[ -e "$APP_DATA_DIR_ABS" && ! -d "$APP_DATA_DIR_ABS" ]]; then
|
|
fail "APP_DATA_DIR must be a directory"
|
|
fi
|
|
|
|
opencloud_paths=(
|
|
"$APP_DATA_DIR_ABS/config"
|
|
"$APP_DATA_DIR_ABS/storage"
|
|
"$APP_DATA_DIR_ABS/apps"
|
|
)
|
|
traefik_paths=(
|
|
"$APP_DATA_DIR_ABS/traefik/dynamic"
|
|
"$APP_DATA_DIR_ABS/traefik/certs"
|
|
)
|
|
|
|
for path in "${opencloud_paths[@]}" "${traefik_paths[@]}"; do
|
|
ensure_no_symlink_components "$path"
|
|
done
|
|
|
|
mkdir -p -- "${opencloud_paths[@]}" "${traefik_paths[@]}"
|
|
for path in "${opencloud_paths[@]}"; do
|
|
chown 1000:1000 -- "$path" 2>/dev/null || true
|
|
done
|
|
|
|
[[ "$OC_DOMAIN_RAW" =~ ^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)*$ ]] || fail "OC_DOMAIN must be a hostname without a scheme, port, or path"
|
|
[[ ${#OC_DOMAIN_RAW} -le 253 ]] || fail "OC_DOMAIN is too long"
|
|
|
|
route_template="$ROOT_DIR/config/traefik/opencloud.yml"
|
|
route_file="$APP_DATA_DIR_ABS/traefik/dynamic/1panel-opencloud-route.yml"
|
|
[[ -f "$route_template" && ! -L "$route_template" ]] || fail "OpenCloud Traefik route template is missing or invalid"
|
|
[[ ! -L "$route_file" ]] || fail "OpenCloud Traefik route must not be a symbolic link: $route_file"
|
|
if [[ -e "$route_file" && ! -f "$route_file" ]]; then
|
|
fail "OpenCloud Traefik route must be a regular file: $route_file"
|
|
fi
|
|
|
|
if [[ ! -e "$route_file" ]]; then
|
|
route_tmp="$(mktemp "${route_file}.tmp.XXXXXX")"
|
|
if ! sed "s/@OC_DOMAIN@/${OC_DOMAIN_RAW}/g" "$route_template" > "$route_tmp"; then
|
|
rm -f -- "$route_tmp"
|
|
fail "Could not create OpenCloud Traefik route"
|
|
fi
|
|
chmod 0644 -- "$route_tmp"
|
|
if ! ln -- "$route_tmp" "$route_file" 2>/dev/null; then
|
|
if [[ ! -f "$route_file" || -L "$route_file" ]]; then
|
|
rm -f -- "$route_tmp"
|
|
fail "Could not create OpenCloud Traefik route"
|
|
fi
|
|
fi
|
|
rm -f -- "$route_tmp"
|
|
fi
|