mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-07-11 00:22:13 +02:00
38423262c8
Bump the default Pangolin version to 1.20.0 in both CT and install scripts. Update the CT upgrade path to validate required 1.20.0 schema objects, clear stale versionMigrations markers when needed, retry migrations once, and abort with a clear error if the schema is still incomplete to avoid a broken runtime.
162 lines
6.2 KiB
Bash
162 lines
6.2 KiB
Bash
#!/usr/bin/env bash
|
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
|
# Copyright (c) 2021-2026 community-scripts ORG
|
|
# Author: Slaviša Arežina (tremor021)
|
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
# Source: https://pangolin.net/ | Github: https://github.com/fosrl/pangolin
|
|
|
|
APP="Pangolin"
|
|
PANGOLIN_VERSION="${PANGOLIN_VERSION:-1.20.0}"
|
|
var_tags="${var_tags:-proxy}"
|
|
var_cpu="${var_cpu:-2}"
|
|
var_ram="${var_ram:-4096}"
|
|
var_disk="${var_disk:-10}"
|
|
var_os="${var_os:-debian}"
|
|
var_version="${var_version:-13}"
|
|
var_arm64="${var_arm64:-yes}"
|
|
var_unprivileged="${var_unprivileged:-1}"
|
|
var_tun="${var_tun:-1}"
|
|
|
|
header_info "$APP"
|
|
variables
|
|
color
|
|
catch_errors
|
|
|
|
function update_script() {
|
|
header_info
|
|
check_container_storage
|
|
check_container_resources
|
|
if [[ ! -d /opt/pangolin ]]; then
|
|
msg_error "No ${APP} Installation Found!"
|
|
exit
|
|
fi
|
|
|
|
ensure_dependencies build-essential python3
|
|
|
|
NODE_VERSION="24" setup_nodejs
|
|
|
|
if check_for_gh_release "pangolin" "fosrl/pangolin" "$PANGOLIN_VERSION" "Pinned to a tested release because Pangolin's schema changes have repeatedly broken unattended updates. To try a newer version at your own risk, run: 'export PANGOLIN_VERSION=<tag>' and re-run update. If it breaks, please open an issue at https://github.com/community-scripts/ProxmoxVE/issues with the error log."; then
|
|
msg_info "Stopping Service"
|
|
systemctl stop pangolin
|
|
systemctl stop gerbil
|
|
msg_info "Service stopped"
|
|
|
|
msg_info "Creating backup"
|
|
tar -czf /opt/pangolin_config_backup.tar.gz -C /opt/pangolin config
|
|
if [[ -f /opt/pangolin/config/db/db.sqlite ]]; then
|
|
cp -a /opt/pangolin/config/db/db.sqlite \
|
|
"/opt/pangolin/config/db/db.sqlite.pre-${PANGOLIN_VERSION}-$(date +%Y%m%d-%H%M%S).bak"
|
|
fi
|
|
msg_ok "Created backup"
|
|
|
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" "$PANGOLIN_VERSION"
|
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_$(arch_resolve)"
|
|
|
|
msg_info "Updating Pangolin"
|
|
cd /opt/pangolin
|
|
$STD npm ci
|
|
$STD npm run set:sqlite
|
|
$STD npm run set:oss
|
|
rm -rf server/private
|
|
$STD npm run db:generate
|
|
$STD npm run build
|
|
$STD npm run build:cli
|
|
cp -R .next/standalone ./
|
|
chmod +x ./dist/cli.mjs
|
|
cp server/db/names.json ./dist/names.json
|
|
cp server/db/ios_models.json ./dist/ios_models.json
|
|
cp server/db/mac_models.json ./dist/mac_models.json
|
|
msg_ok "Updated Pangolin"
|
|
|
|
msg_info "Restoring config"
|
|
tar -xzf /opt/pangolin_config_backup.tar.gz -C /opt/pangolin --overwrite
|
|
rm -f /opt/pangolin_config_backup.tar.gz
|
|
msg_ok "Restored config"
|
|
|
|
if ! grep -q '^ExecStartPre=/usr/bin/node dist/migrations.mjs' /etc/systemd/system/pangolin.service 2>/dev/null; then
|
|
msg_info "Adding migration step to pangolin.service"
|
|
sed -i '/^ExecStart=\/usr\/bin\/node --enable-source-maps dist\/server.mjs/i ExecStartPre=/usr/bin/node dist/migrations.mjs' /etc/systemd/system/pangolin.service
|
|
systemctl daemon-reload
|
|
msg_ok "Updated pangolin.service"
|
|
fi
|
|
|
|
sqlite_table_exists() {
|
|
local db_path="$1"
|
|
local table_name="$2"
|
|
sqlite3 "$db_path" "SELECT 1 FROM sqlite_master WHERE type='table' AND name='$table_name' LIMIT 1;" 2>/dev/null | grep -q '^1$'
|
|
}
|
|
|
|
sqlite_column_exists() {
|
|
local db_path="$1"
|
|
local table_name="$2"
|
|
local column_name="$3"
|
|
sqlite3 "$db_path" "PRAGMA table_info('$table_name');" 2>/dev/null | awk -F'|' -v col="$column_name" '$2==col{found=1} END{exit !found}'
|
|
}
|
|
|
|
sqlite_schema_ready_for_120() {
|
|
local db_path="$1"
|
|
sqlite_table_exists "$db_path" "remoteExitNodePreferenceLabels" &&
|
|
sqlite_table_exists "$db_path" "remoteExitNodeResources" &&
|
|
sqlite_table_exists "$db_path" "launcherViews" &&
|
|
sqlite_column_exists "$db_path" "domains" "customCertResolver" &&
|
|
sqlite_column_exists "$db_path" "domains" "lastCheckedAt"
|
|
}
|
|
|
|
run_sqlite_migrations() {
|
|
ENVIRONMENT=prod $STD node dist/migrations.mjs
|
|
}
|
|
|
|
msg_info "Running database migrations"
|
|
cd /opt/pangolin
|
|
SQLITE_DB="/opt/pangolin/config/db/db.sqlite"
|
|
if [[ -f "$SQLITE_DB" ]]; then
|
|
if ! sqlite_table_exists "$SQLITE_DB" "statusHistory"; then
|
|
sqlite3 "$SQLITE_DB" "DELETE FROM versionMigrations;" 2>/dev/null || true
|
|
fi
|
|
|
|
if [[ "$PANGOLIN_VERSION" == "1.20.0" ]] &&
|
|
sqlite3 "$SQLITE_DB" "SELECT 1 FROM versionMigrations WHERE version='1.20.0' LIMIT 1;" 2>/dev/null | grep -q '^1$' &&
|
|
! sqlite_schema_ready_for_120 "$SQLITE_DB"; then
|
|
msg_info "Detected stale migration marker for 1.20.0; forcing replay"
|
|
sqlite3 "$SQLITE_DB" "DELETE FROM versionMigrations WHERE version='1.20.0';" 2>/dev/null || true
|
|
fi
|
|
fi
|
|
|
|
run_sqlite_migrations
|
|
|
|
if [[ -f "$SQLITE_DB" ]] && [[ "$PANGOLIN_VERSION" == "1.20.0" ]] && ! sqlite_schema_ready_for_120 "$SQLITE_DB"; then
|
|
msg_info "Schema check failed after first pass; retrying 1.20.0 migration"
|
|
sqlite3 "$SQLITE_DB" "DELETE FROM versionMigrations WHERE version='1.20.0';" 2>/dev/null || true
|
|
run_sqlite_migrations
|
|
fi
|
|
|
|
if [[ -f "$SQLITE_DB" ]] && [[ "$PANGOLIN_VERSION" == "1.20.0" ]] && ! sqlite_schema_ready_for_120 "$SQLITE_DB"; then
|
|
msg_error "SQLite schema is still incomplete after migration replay (expected 1.20.0 schema). Aborting update to prevent broken runtime."
|
|
exit 1
|
|
fi
|
|
|
|
msg_ok "Ran database migrations"
|
|
|
|
msg_info "Updating Badger plugin version"
|
|
BADGER_VERSION=$(get_latest_github_release "fosrl/badger" "false")
|
|
sed -i "s/version: \"v[0-9.]*\"/version: \"$BADGER_VERSION\"/g" /opt/pangolin/config/traefik/traefik_config.yml
|
|
msg_ok "Updated Badger plugin version"
|
|
|
|
msg_info "Starting Services"
|
|
systemctl start pangolin
|
|
systemctl start gerbil
|
|
msg_ok "Started Services"
|
|
msg_ok "Updated successfully!"
|
|
fi
|
|
exit
|
|
}
|
|
|
|
start
|
|
build_container
|
|
description
|
|
|
|
msg_ok "Completed successfully!\n"
|
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
|
echo -e "${GATEWAY}${BGN}https://<YOUR_PANGOLIN_URL>${CL}"
|