Compare commits

..

6 Commits

Author SHA1 Message Date
CanbiZ (MickLesk)
d84770e215 chore(ct,tools): sync Source headers with install/ and add Github links to addon scripts 2026-02-24 14:36:19 +01:00
CanbiZ (MickLesk)
8deb4401b1 revert: restore misc/build.func and misc/core.func to main state
These error-handler fixes belong to fix/error-handler-recovery, not to
this sources-only branch.
2026-02-24 14:30:07 +01:00
CanbiZ (MickLesk)
b1edd80a96 chore(install): add Github source links to all fetch_and_deploy scripts
77 additional install scripts had fetch_and_deploy_gh_release calls but
no GitHub link in the Source header. Merged the primary app repo into
the Source header as:
  # Source: https://website.com/ | Github: https://github.com/OWNER/REPO

Where multiple fetch_and_deploy calls existed (app + dependency), the
primary app repo was selected:
- ersatztv: ErsatzTV/ErsatzTV (not ffmpeg)
- firefly: firefly-iii/firefly-iii (not data-importer)
- komga: gotson/komga (not kepubify dep)
- sabnzbd: sabnzbd/sabnzbd (not par2cmdline-turbo dep)
- signoz: SigNoz/signoz (not otel-collector)
- tunarr: chrisbenincasa/tunarr (not ffmpeg dep)

Also fixed cosmos-install.sh double https:// in Source URL.

Skipped: autocaliweb (source already on codeberg, GitHub repos are deps only)
2026-02-24 14:28:45 +01:00
CanbiZ (MickLesk)
da422b1036 chore(install): add Github source links to all setup_nodejs scripts
52 install scripts had a project website in '# Source:' but no GitHub
link. Merged the GitHub repo URL into the Source header as:
  # Source: https://website.com/ | Github: https://github.com/OWNER/REPO

Repos sourced from fetch_and_deploy_gh_release calls, get_latest_github_release
calls, or known project repos for npm/pip installed apps.

Two scripts (fumadocs, pve-scripts-local) had no Source line at all —
added one. Shinobi skipped (GitLab-only, no GitHub repo).
2026-02-24 14:21:43 +01:00
CanbiZ (MickLesk)
7bb14b4d22 Update build.func 2026-02-24 14:03:09 +01:00
CanbiZ (MickLesk)
75c0b1bfc9 fix(error-handler): prevent silent() from re-enabling error handling during recovery
Root cause: silent() (core.func) unconditionally calls set -Eeuo pipefail
and trap 'error_handler' ERR after every command. When build_container()
intentionally disables error handling for its recovery section, any
intermediate call through silent()/ re-enables it. This causes the
grep/sed pipeline for missing_cmd extraction to trigger error_handler
(grep returns exit code 1 on no match + pipefail = fatal).

Fixes:
1. silent(): Save errexit state before disabling, only restore if it was
   active. Callers that intentionally disabled error handling (e.g.
   build_container recovery) are no longer silently re-enabled.

2. build.func: Add || true to missing_cmd grep pipeline as defense-in-depth
   against pipeline failure propagation.

3. build.func: Add explicit set +Eeuo pipefail / trap - ERR after
   post_update_to_api() call, before error classification grep/sed section.

4. build.func: Remove stale global combined_log variable from variables()
   that used a different path format (/tmp/install-SESSION-combined.log)
   than the actual local variable (/tmp/NSAPP-CTID-SESSION.log). The global
   was never written to and caused confusion when error_handler displayed it.
2026-02-24 13:51:27 +01:00
17 changed files with 136 additions and 289 deletions

View File

@@ -407,53 +407,27 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details>
## 2026-02-25
### 🚀 Updated Scripts
- #### 🔧 Refactor
- OpenProject: Various fixes [@tremor021](https://github.com/tremor021) ([#12246](https://github.com/community-scripts/ProxmoxVE/pull/12246))
### 💾 Core
- #### 🐞 Bug Fixes
- Fix detection of ssh keys [@1-tempest](https://github.com/1-tempest) ([#12230](https://github.com/community-scripts/ProxmoxVE/pull/12230))
## 2026-02-24
### 🚀 Updated Scripts
- several scripts: add additional github link in source [@MickLesk](https://github.com/MickLesk) ([#12282](https://github.com/community-scripts/ProxmoxVE/pull/12282))
- adds further documentation during the installation script. [@d12rio](https://github.com/d12rio) ([#12248](https://github.com/community-scripts/ProxmoxVE/pull/12248))
- adds further documentation during the installation script. [@d12rio](https://github.com/d12rio) ([#12248](https://github.com/community-scripts/ProxmoxVE/pull/12248))
- #### 🐞 Bug Fixes
- [Fix] PatchMon: remove VITE_API_URL from frontend env [@vhsdream](https://github.com/vhsdream) ([#12294](https://github.com/community-scripts/ProxmoxVE/pull/12294))
- fix(searxng): remove orphaned fi causing syntax error [@mark-jeffrey](https://github.com/mark-jeffrey) ([#12283](https://github.com/community-scripts/ProxmoxVE/pull/12283))
- Refactor n8n [@MickLesk](https://github.com/MickLesk) ([#12264](https://github.com/community-scripts/ProxmoxVE/pull/12264))
- Firefly: PHP bump [@tremor021](https://github.com/tremor021) ([#12247](https://github.com/community-scripts/ProxmoxVE/pull/12247))
- #### ✨ New Features
- Databasus: add mariadb path for mysql/mariadb backups | add mongodb database tools [@MickLesk](https://github.com/MickLesk) ([#12259](https://github.com/community-scripts/ProxmoxVE/pull/12259))
- make searxng updateable [@shtefko](https://github.com/shtefko) ([#12207](https://github.com/community-scripts/ProxmoxVE/pull/12207))
- #### 💥 Breaking Changes
- fix: wealthfolio for v3 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11765](https://github.com/community-scripts/ProxmoxVE/pull/11765))
- #### 🔧 Refactor
- bump various scripts from Node 22 to 24 [@MickLesk](https://github.com/MickLesk) ([#12265](https://github.com/community-scripts/ProxmoxVE/pull/12265))
### 💾 Core
- #### 🐞 Bug Fixes
- core: fix broken "command not found" after err_trap [@MickLesk](https://github.com/MickLesk) ([#12280](https://github.com/community-scripts/ProxmoxVE/pull/12280))
- #### ✨ New Features
- tools.func: add get_latest_gh_tag helper function [@MickLesk](https://github.com/MickLesk) ([#12261](https://github.com/community-scripts/ProxmoxVE/pull/12261))

View File

@@ -38,31 +38,6 @@ function update_script() {
cp /opt/databasus/.env /opt/databasus.env.bak
msg_ok "Backed up Configuration"
msg_info "Ensuring Database Clients"
# Create PostgreSQL version symlinks for compatibility
for v in 12 13 14 15 16 18; do
ln -sf /usr/lib/postgresql/17 /usr/lib/postgresql/$v
done
# Install MongoDB Database Tools via direct .deb (no APT repo for Debian 13)
if ! command -v mongodump &>/dev/null; then
[[ "$(get_os_info id)" == "ubuntu" ]] && MONGO_DIST="ubuntu2204" || MONGO_DIST="debian12"
fetch_and_deploy_from_url "https://fastdl.mongodb.org/tools/db/mongodb-database-tools-${MONGO_DIST}-x86_64-100.14.1.deb"
fi
[[ -f /usr/bin/mongodump ]] && ln -sf /usr/bin/mongodump /usr/local/mongodb-database-tools/bin/mongodump
[[ -f /usr/bin/mongorestore ]] && ln -sf /usr/bin/mongorestore /usr/local/mongodb-database-tools/bin/mongorestore
# Create MariaDB and MySQL client symlinks for compatibility
ensure_dependencies mariadb-client
mkdir -p /usr/local/mariadb-{10.6,12.1}/bin /usr/local/mysql-{5.7,8.0,8.4,9}/bin /usr/local/mongodb-database-tools/bin
for dir in /usr/local/mariadb-{10.6,12.1}/bin; do
ln -sf /usr/bin/mariadb-dump "$dir/mariadb-dump"
ln -sf /usr/bin/mariadb "$dir/mariadb"
done
for dir in /usr/local/mysql-{5.7,8.0,8.4,9}/bin; do
ln -sf /usr/bin/mariadb-dump "$dir/mysqldump"
ln -sf /usr/bin/mariadb "$dir/mysql"
done
msg_ok "Ensured Database Clients"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "databasus" "databasus/databasus" "tarball" "latest" "/opt/databasus"
msg_info "Updating Databasus"
@@ -74,7 +49,6 @@ function update_script() {
$STD /root/go/bin/swag init -g cmd/main.go -o swagger
$STD env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o databasus ./cmd/main.go
mv /opt/databasus/backend/databasus /opt/databasus/databasus
mkdir -p /opt/databasus/ui/build
cp -r /opt/databasus/frontend/dist/* /opt/databasus/ui/build/
cp -r /opt/databasus/backend/migrations /opt/databasus/
chown -R postgres:postgres /opt/databasus

View File

@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
@@ -27,11 +27,10 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating OpenProject"
msg_info "Updating ${APP}"
$STD apt update
$STD apt install --only-upgrade -y openproject
msg_ok "Updated OpenProject"
msg_ok "Updated ${APP}"
msg_ok "Updated successfully!"
exit
}

View File

@@ -51,10 +51,13 @@ function update_script() {
msg_info "Updating PatchMon"
VERSION=$(get_latest_github_release "PatchMon/PatchMon")
PROTO="$(sed -n '/SERVER_PROTOCOL/s/[^=]*=//p' /opt/backend.env)"
HOST="$(sed -n '/SERVER_HOST/s/[^=]*=//p' /opt/backend.env)"
SERVER_PORT="$(sed -n '/SERVER_PORT/s/[^=]*=//p' /opt/backend.env)"
[[ "$PROTO" == "http" ]] && PORT=":3001"
sed -i 's/PORT=3399/PORT=3001/' /opt/backend.env
sed -i -e "s/VERSION=.*/VERSION=$VERSION/" \
-e '/^VITE_API_URL/d' /opt/frontend.env
-e "\|VITE_API_URL=|s|http.*|${PROTO:-http}://${HOST:-$LOCAL_IP}${PORT:-}/api/v1|" /opt/frontend.env
export NODE_ENV=production
cd /opt/patchmon
$STD npm install --no-audit --no-fund --no-save --ignore-scripts

View File

@@ -52,6 +52,7 @@ function update_script() {
systemctl start searxng
msg_ok "Started Services"
msg_ok "Updated successfully!"
fi
exit
}
start

View File

@@ -43,15 +43,16 @@ function update_script() {
msg_info "Building Frontend (patience)"
cd /opt/wealthfolio
export BUILD_TARGET=web
$STD pnpm install --frozen-lockfile
$STD pnpm --filter frontend... build
$STD pnpm tsc
$STD pnpm vite build
msg_ok "Built Frontend"
msg_info "Building Backend (patience)"
cd /opt/wealthfolio/src-server
source ~/.cargo/env
$STD cargo build --release --manifest-path apps/server/Cargo.toml
cp /opt/wealthfolio/target/release/wealthfolio-server /usr/local/bin/wealthfolio-server
$STD cargo build --release --manifest-path Cargo.toml
cp /opt/wealthfolio/src-server/target/release/wealthfolio-server /usr/local/bin/wealthfolio-server
chmod +x /usr/local/bin/wealthfolio-server
msg_ok "Built Backend"
@@ -62,7 +63,7 @@ function update_script() {
msg_ok "Restored Data"
msg_info "Cleaning Up"
rm -rf /opt/wealthfolio/target
rm -rf /opt/wealthfolio/src-server/target
rm -rf /root/.cargo/registry
rm -rf /opt/wealthfolio/node_modules
msg_ok "Cleaned Up"

View File

@@ -1,5 +1,5 @@
{
"generated": "2026-02-25T06:25:10Z",
"generated": "2026-02-24T12:15:44Z",
"versions": [
{
"slug": "2fauth",
@@ -200,9 +200,9 @@
{
"slug": "cleanuparr",
"repo": "Cleanuparr/Cleanuparr",
"version": "v2.7.5",
"version": "v2.7.4",
"pinned": false,
"date": "2026-02-24T17:11:50Z"
"date": "2026-02-23T18:41:16Z"
},
{
"slug": "cloudreve",
@@ -214,9 +214,9 @@
{
"slug": "comfyui",
"repo": "comfyanonymous/ComfyUI",
"version": "v0.15.0",
"version": "v0.14.2",
"pinned": false,
"date": "2026-02-24T20:56:09Z"
"date": "2026-02-18T06:12:02Z"
},
{
"slug": "commafeed",
@@ -361,16 +361,16 @@
{
"slug": "endurain",
"repo": "endurain-project/endurain",
"version": "v0.17.5",
"version": "v0.17.4",
"pinned": false,
"date": "2026-02-24T14:51:03Z"
"date": "2026-02-11T04:54:22Z"
},
{
"slug": "ersatztv",
"repo": "ErsatzTV/ErsatzTV",
"version": "v26.3.0",
"version": "v26.2.0",
"pinned": false,
"date": "2026-02-24T21:36:34Z"
"date": "2026-02-02T20:54:26Z"
},
{
"slug": "excalidraw",
@@ -613,9 +613,9 @@
{
"slug": "jackett",
"repo": "Jackett/Jackett",
"version": "v0.24.1205",
"version": "v0.24.1193",
"pinned": false,
"date": "2026-02-25T05:49:14Z"
"date": "2026-02-24T05:58:04Z"
},
{
"slug": "jellystat",
@@ -746,9 +746,9 @@
{
"slug": "libretranslate",
"repo": "LibreTranslate/LibreTranslate",
"version": "v1.9.4",
"version": "v1.9.3",
"pinned": false,
"date": "2026-02-24T17:06:05Z"
"date": "2026-02-21T19:08:33Z"
},
{
"slug": "lidarr",
@@ -977,9 +977,9 @@
{
"slug": "open-archiver",
"repo": "LogicLabs-OU/OpenArchiver",
"version": "v0.4.2",
"version": "v0.4.1",
"pinned": false,
"date": "2026-02-24T20:47:40Z"
"date": "2026-01-17T12:24:31Z"
},
{
"slug": "opencloud",
@@ -1208,9 +1208,9 @@
{
"slug": "pulse",
"repo": "rcourtman/Pulse",
"version": "v5.1.14",
"version": "v5.1.13",
"pinned": false,
"date": "2026-02-25T00:11:58Z"
"date": "2026-02-22T12:40:41Z"
},
{
"slug": "pve-scripts-local",
@@ -1285,9 +1285,9 @@
{
"slug": "recyclarr",
"repo": "recyclarr/recyclarr",
"version": "v8.3.1",
"version": "v8.2.1",
"pinned": false,
"date": "2026-02-25T01:01:31Z"
"date": "2026-02-22T19:19:49Z"
},
{
"slug": "reitti",
@@ -1334,9 +1334,9 @@
{
"slug": "scanopy",
"repo": "scanopy/scanopy",
"version": "v0.14.8",
"version": "v0.14.7",
"pinned": false,
"date": "2026-02-24T16:45:30Z"
"date": "2026-02-23T01:36:44Z"
},
{
"slug": "scraparr",
@@ -1369,9 +1369,9 @@
{
"slug": "semaphore",
"repo": "semaphoreui/semaphore",
"version": "v2.17.14",
"version": "v2.17.12",
"pinned": false,
"date": "2026-02-24T14:27:03Z"
"date": "2026-02-20T09:16:50Z"
},
{
"slug": "shelfmark",
@@ -1383,9 +1383,9 @@
{
"slug": "signoz",
"repo": "SigNoz/signoz-otel-collector",
"version": "v0.144.1",
"version": "v0.142.1",
"pinned": false,
"date": "2026-02-25T05:57:17Z"
"date": "2026-02-21T18:04:07Z"
},
{
"slug": "silverbullet",
@@ -1621,9 +1621,9 @@
{
"slug": "upgopher",
"repo": "wanetty/upgopher",
"version": "v1.14.0",
"version": "v1.13.0",
"pinned": false,
"date": "2026-02-24T22:43:34Z"
"date": "2026-01-16T20:26:34Z"
},
{
"slug": "upsnap",
@@ -1679,7 +1679,7 @@
"repo": "meilisearch/meilisearch",
"version": "v1.36.0",
"pinned": false,
"date": "2026-02-23T08:13:32Z"
"date": ""
},
{
"slug": "warracker",
@@ -1712,9 +1712,9 @@
{
"slug": "wealthfolio",
"repo": "afadil/wealthfolio",
"version": "v3.0.0",
"version": "v2.1.0",
"pinned": false,
"date": "2026-02-24T22:37:05Z"
"date": "2025-12-01T21:57:36Z"
},
{
"slug": "web-check",
@@ -1747,9 +1747,9 @@
{
"slug": "wizarr",
"repo": "wizarrrr/wizarr",
"version": "v2026.2.1",
"version": "v2026.2.0",
"pinned": false,
"date": "2026-02-25T01:07:56Z"
"date": "2026-02-23T19:25:28Z"
},
{
"slug": "writefreely",
@@ -1768,9 +1768,9 @@
{
"slug": "yubal",
"repo": "guillevc/yubal",
"version": "v0.6.2",
"version": "v0.6.1",
"pinned": false,
"date": "2026-02-24T15:15:46Z"
"date": "2026-02-18T23:24:16Z"
},
{
"slug": "zigbee2mqtt",
@@ -1789,9 +1789,9 @@
{
"slug": "zitadel",
"repo": "zitadel/zitadel",
"version": "v4.11.1",
"version": "v4.11.0",
"pinned": false,
"date": "2026-02-25T06:13:13Z"
"date": "2026-02-16T09:48:38Z"
},
{
"slug": "zoraxy",

View File

@@ -23,7 +23,7 @@
"ram": 4096,
"hdd": 8,
"os": "Debian",
"version": "13"
"version": "12"
}
}
],
@@ -31,10 +31,5 @@
"username": "admin",
"password": "admin"
},
"notes": [
{
"text": "If you want to update from v15.x to v17.x, please read `https://www.openproject.org/docs/installation-and-operations/operation/upgrading/#major-upgrades` before doing so.",
"type": "warning"
}
]
"notes": []
}

View File

@@ -15,40 +15,14 @@ update_os
msg_info "Installing Dependencies"
$STD apt install -y \
nginx \
valkey \
mariadb-client \
rclone
nginx \
valkey
msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql
setup_go
NODE_VERSION="24" setup_nodejs
msg_info "Installing Database Clients"
# Create PostgreSQL version symlinks for compatibility
for v in 12 13 14 15 16 18; do
ln -sf /usr/lib/postgresql/17 /usr/lib/postgresql/$v
done
# Install MongoDB Database Tools via direct .deb (no APT repo for Debian 13)
[[ "$(get_os_info id)" == "ubuntu" ]] && MONGO_DIST="ubuntu2204" || MONGO_DIST="debian12"
MONGO_VERSION=$(get_latest_gh_tag "mongodb/mongo-tools" "100." || echo "100.14.1")
fetch_and_deploy_from_url "https://fastdl.mongodb.org/tools/db/mongodb-database-tools-${MONGO_DIST}-x86_64-${MONGO_VERSION}.deb"
mkdir -p /usr/local/mongodb-database-tools/bin
[[ -f /usr/bin/mongodump ]] && ln -sf /usr/bin/mongodump /usr/local/mongodb-database-tools/bin/mongodump
[[ -f /usr/bin/mongorestore ]] && ln -sf /usr/bin/mongorestore /usr/local/mongodb-database-tools/bin/mongorestore
# Create MariaDB and MySQL client symlinks for compatibility
mkdir -p /usr/local/mariadb-{10.6,12.1}/bin /usr/local/mysql-{5.7,8.0,8.4,9}/bin
for dir in /usr/local/mariadb-{10.6,12.1}/bin; do
ln -sf /usr/bin/mariadb-dump "$dir/mariadb-dump"
ln -sf /usr/bin/mariadb "$dir/mariadb"
done
for dir in /usr/local/mysql-{5.7,8.0,8.4,9}/bin; do
ln -sf /usr/bin/mariadb-dump "$dir/mysqldump"
ln -sf /usr/bin/mariadb "$dir/mysql"
done
msg_ok "Installed Database Clients"
fetch_and_deploy_gh_release "databasus" "databasus/databasus" "tarball" "latest" "/opt/databasus"
msg_info "Building Databasus (Patience)"
@@ -73,6 +47,10 @@ msg_ok "Built Databasus"
msg_info "Configuring Databasus"
JWT_SECRET=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -hex 32)
# Create PostgreSQL version symlinks for compatibility
for v in 12 13 14 15 16 18; do
ln -sf /usr/lib/postgresql/17 /usr/lib/postgresql/$v
done
# Install goose for migrations
$STD go install github.com/pressly/goose/v3/cmd/goose@latest
ln -sf /root/go/bin/goose /usr/local/bin/goose

View File

@@ -72,7 +72,7 @@ cat <<EOF >/etc/apache2/sites-available/firefly.conf
</VirtualHost>
EOF
chown www-data:www-data /opt/firefly/storage/oauth-*.key
$STD a2enmod php8.5
$STD a2enmod php8.4
$STD a2enmod rewrite
$STD a2ensite firefly.conf
$STD a2dissite 000-default.conf

View File

@@ -14,30 +14,19 @@ network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y \
apt-transport-https \
build-essential \
autoconf
$STD apt install -y apt-transport-https
msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql
PG_DB_NAME="openproject" PG_DB_USER="openproject" setup_postgresql_db
API_KEY=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
echo "OpenProject API Key: $API_KEY" >>~/openproject.creds
fetch_and_deploy_gh_release "jemalloc" "jemalloc/jemalloc" "tarball"
msg_info "Compiling jemalloc (Patience)"
cd /opt/jemalloc
$STD ./autogen.sh
$STD make
$STD make install
msg_ok "Compiled jemalloc"
setup_deb822_repo \
"openproject" \
"https://packages.openproject.com/srv/deb/opf/openproject/gpg-key.gpg" \
"https://packages.openproject.com/srv/deb/opf/openproject/stable/17/debian/" \
"12"
msg_info "Setting up OpenProject Repository"
curl -fsSL "https://dl.packager.io/srv/opf/openproject/key" | gpg --dearmor >/etc/apt/trusted.gpg.d/packager-io.gpg
curl -fsSL "https://dl.packager.io/srv/opf/openproject/stable/15/installer/debian/12.repo" -o "/etc/apt/sources.list.d/openproject.list"
$STD apt update
msg_ok "Setup OpenProject Repository"
msg_info "Installing OpenProject"
$STD apt install -y openproject
@@ -71,11 +60,6 @@ openproject/admin_email admin@example.net
openproject/default_language en
EOF
$STD sudo openproject configure
systemctl stop openproject-web-1
if ! grep -qF 'Environment=LD_PRELOAD=/usr/local/lib/libjemalloc.so.2' /etc/systemd/system/openproject-web-1.service; then
sed -i '/^\[Service\]/a Environment=LD_PRELOAD=/usr/local/lib/libjemalloc.so.2' /etc/systemd/system/openproject-web-1.service
fi
systemctl start openproject-web-1
msg_ok "Configured OpenProject"
motd_ssh

View File

@@ -34,6 +34,7 @@ $STD npm install --no-audit --no-fund --no-save --ignore-scripts
cd /opt/patchmon/frontend
cat <<EOF >./.env
VITE_API_URL=http://${LOCAL_IP}:3001/api/v1
VITE_APP_NAME=PatchMon
VITE_APP_VERSION=${VERSION}
EOF

View File

@@ -28,15 +28,15 @@ fetch_and_deploy_gh_release "wealthfolio" "afadil/wealthfolio" "tarball"
msg_info "Building Frontend (patience)"
cd /opt/wealthfolio
export BUILD_TARGET=web
$STD pnpm install --frozen-lockfile
$STD pnpm --filter frontend... build
$STD pnpm tsc
$STD pnpm vite build
msg_ok "Built Frontend"
msg_info "Building Backend (patience)"
source ~/.cargo/env
$STD cargo build --release --manifest-path apps/server/Cargo.toml
cp /opt/wealthfolio/target/release/wealthfolio-server /usr/local/bin/wealthfolio-server
cd /opt/wealthfolio/src-server
$STD cargo build --release --manifest-path Cargo.toml
cp /opt/wealthfolio/src-server/target/release/wealthfolio-server /usr/local/bin/wealthfolio-server
chmod +x /usr/local/bin/wealthfolio-server
msg_ok "Built Backend"
@@ -58,7 +58,7 @@ echo "WF_PASSWORD=${WF_PASSWORD}" >~/wealthfolio.creds
msg_ok "Configured Wealthfolio"
msg_info "Cleaning Up"
rm -rf /opt/wealthfolio/target
rm -rf /opt/wealthfolio/src-server/target
rm -rf /root/.cargo/registry
rm -rf /opt/wealthfolio/node_modules
msg_ok "Cleaned Up"

View File

@@ -312,8 +312,7 @@ json_escape() {
s=${s//$'\r'/}
s=${s//$'\t'/\\t}
# Remove any remaining control characters (0x00-0x1F except those already handled)
# Also remove DEL (0x7F) and invalid high bytes that break JSON parsers
s=$(printf '%s' "$s" | tr -d '\000-\010\013\014\016-\037\177')
s=$(printf '%s' "$s" | tr -d '\000-\010\013\014\016-\037')
printf '%s' "$s"
}
@@ -983,7 +982,7 @@ EOF
fi
# All 3 attempts failed — do NOT set POST_UPDATE_DONE=true.
# This allows the EXIT trap (on_exit in error_handler.func) to retry.
# This allows the EXIT trap (api_exit_script) to retry with 3 fresh attempts.
# No infinite loop risk: EXIT trap fires exactly once.
}

View File

@@ -38,18 +38,17 @@
# - Captures app-declared resource defaults (CPU, RAM, Disk)
# ------------------------------------------------------------------------------
variables() {
NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces.
var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP.
INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern.
PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase
DIAGNOSTICS="no" # Safe default: no telemetry until user consents via diagnostics_check()
METHOD="default" # sets the METHOD variable to "default", used for the API call.
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable.
EXECUTION_ID="${RANDOM_UUID}" # Unique execution ID for telemetry record identification (unique-indexed in PocketBase)
SESSION_ID="${RANDOM_UUID:0:8}" # Short session ID (first 8 chars of UUID) for log files
BUILD_LOG="/tmp/create-lxc-${SESSION_ID}.log" # Host-side container creation log
# NOTE: combined_log is constructed locally in build_container() and ensure_log_on_host()
# as "/tmp/${NSAPP}-${CTID}-${SESSION_ID}.log" (requires CTID, not available here)
NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces.
var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP.
INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern.
PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase
DIAGNOSTICS="no" # Safe default: no telemetry until user consents via diagnostics_check()
METHOD="default" # sets the METHOD variable to "default", used for the API call.
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable.
EXECUTION_ID="${RANDOM_UUID}" # Unique execution ID for telemetry record identification (unique-indexed in PocketBase)
SESSION_ID="${RANDOM_UUID:0:8}" # Short session ID (first 8 chars of UUID) for log files
BUILD_LOG="/tmp/create-lxc-${SESSION_ID}.log" # Host-side container creation log
combined_log="/tmp/install-${SESSION_ID}-combined.log" # Combined log (build + install) for failed installations
CTTYPE="${CTTYPE:-${CT_TYPE:-1}}"
# Parse dev_mode early
@@ -693,7 +692,7 @@ find_host_ssh_keys() {
/^[[:space:]]*#/ {next}
/^[[:space:]]*$/ {next}
{print}
' | grep -E -c "$re" || true)
' | grep -E -c '"$re"' || true)
if ((c > 0)); then
files+=("$f")
@@ -1851,7 +1850,7 @@ advanced_settings() {
# ═══════════════════════════════════════════════════════════════════════════
# STEP 2: Root Password
# ════════════════════════════════════════════════════════════════════════<EFBFBD><EFBFBD><EFBFBD>══
# ══════════════════════════════════════════════════════════════════════════
2)
if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "ROOT PASSWORD" \
@@ -4098,11 +4097,6 @@ EOF'
# Installation failed?
if [[ $install_exit_code -ne 0 ]]; then
# Prevent SIGTSTP (Ctrl+Z) from suspending the script during recovery.
# In non-interactive shells (bash -c), background processes (spinner) can
# trigger terminal-related signals that stop the entire process group.
trap '' TSTP
msg_error "Installation failed in container ${CTID} (exit code: ${install_exit_code})"
# Copy install log from container BEFORE API call so get_error_text() can read it
@@ -4178,19 +4172,7 @@ EOF'
fi
# Report failure to telemetry API (now with log available on host)
# NOTE: Do NOT use msg_info/spinner here — the background spinner process
# causes SIGTSTP in non-interactive shells (bash -c "$(curl ...)"), which
# stops the entire process group and prevents the recovery dialog from appearing.
$STD echo -e "${TAB}⏳ Reporting failure to telemetry..."
post_update_to_api "failed" "$install_exit_code"
$STD echo -e "${TAB}${CM:-} Failure reported"
# Defense-in-depth: Ensure error handling stays disabled during recovery.
# Some functions (e.g. silent/$STD) unconditionally re-enable set -Eeuo pipefail
# and trap 'error_handler' ERR. If any code path above called such a function,
# the grep/sed pipelines below would trigger error_handler on non-match (exit 1).
set +Eeuo pipefail
trap - ERR
# Show combined log location
if [[ -n "$CTID" && -n "${SESSION_ID:-}" ]]; then
@@ -4305,7 +4287,7 @@ EOF'
if [[ "$is_cmd_not_found" == true ]]; then
local missing_cmd=""
if [[ -f "$combined_log" ]]; then
missing_cmd=$(grep -oiE '[a-zA-Z0-9_.-]+: command not found' "$combined_log" 2>/dev/null | tail -1 | sed 's/: command not found//') || true
missing_cmd=$(grep -oiE '[a-zA-Z0-9_.-]+: command not found' "$combined_log" | tail -1 | sed 's/: command not found//')
fi
if [[ -n "$missing_cmd" ]]; then
echo -e "${TAB}${INFO} Missing command: ${GN}${missing_cmd}${CL}"
@@ -4547,12 +4529,8 @@ EOF'
# Force one final status update attempt after cleanup
# This ensures status is updated even if the first attempt failed (e.g., HTTP 400)
$STD echo -e "${TAB}⏳ Finalizing telemetry report..."
post_update_to_api "failed" "$install_exit_code" "force"
$STD echo -e "${TAB}${CM:-} Telemetry finalized"
# Restore default SIGTSTP handling before exit
trap - TSTP
exit $install_exit_code
fi
@@ -5622,21 +5600,44 @@ ensure_log_on_host() {
fi
}
# ==============================================================================
# TRAP MANAGEMENT
# ==============================================================================
# All traps (ERR, EXIT, INT, TERM, HUP) are set by catch_errors() in
# error_handler.func — called at the top of this file after sourcing.
# ------------------------------------------------------------------------------
# api_exit_script()
#
# Do NOT set duplicate traps here. The handlers in error_handler.func
# (on_exit, on_interrupt, on_terminate, on_hangup, error_handler) already:
# - Send telemetry via post_update_to_api / _send_abort_telemetry
# - Stop orphaned containers via _stop_container_if_installing
# - Collect logs via ensure_log_on_host
# - Clean up lock files and spinner processes
#
# Previously, inline traps here overwrote catch_errors() traps, causing:
# - error_handler() never fired (no error output, no cleanup dialog)
# - on_hangup() never fired (SSH disconnect → stuck records)
# - Duplicated logic in two places (hard to debug)
# ==============================================================================
# - Exit trap handler for reporting to API telemetry
# - Captures exit code and reports to PocketBase using centralized error descriptions
# - Uses explain_exit_code() from api.func for consistent error messages
# - ALWAYS sends telemetry FIRST before log collection to prevent pct pull
# hangs from blocking status updates (container may be dead/unresponsive)
# - For non-zero exit codes: posts "failed" status
# - For zero exit codes where post_update_to_api was never called:
# catches orphaned "installing" records (e.g., script exited cleanly
# but description() was never reached)
# ------------------------------------------------------------------------------
api_exit_script() {
local exit_code=$?
if [ $exit_code -ne 0 ]; then
# ALWAYS send telemetry FIRST - ensure status is reported even if
# ensure_log_on_host hangs (e.g. pct pull on dead container)
post_update_to_api "failed" "$exit_code" 2>/dev/null || true
# Best-effort log collection (non-critical after telemetry is sent)
if declare -f ensure_log_on_host >/dev/null 2>&1; then
ensure_log_on_host 2>/dev/null || true
fi
# Stop orphaned container if we're in the install phase
if [[ "${CONTAINER_INSTALLING:-}" == "true" && -n "${CTID:-}" ]] && command -v pct &>/dev/null; then
pct stop "$CTID" 2>/dev/null || true
fi
elif [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then
# Script exited with 0 but never sent a completion status
# exit_code=0 is never an error — report as success
post_update_to_api "done" "0"
fi
}
if command -v pveversion >/dev/null 2>&1; then
trap 'api_exit_script' EXIT
fi
trap 'local _ec=$?; if [[ $_ec -ne 0 ]]; then post_update_to_api "failed" "$_ec" 2>/dev/null || true; if declare -f ensure_log_on_host &>/dev/null; then ensure_log_on_host 2>/dev/null || true; fi; fi' ERR
trap 'post_update_to_api "failed" "129" 2>/dev/null || true; if [[ -n "${CTID:-}" ]] && command -v pct &>/dev/null; then pct stop "$CTID" 2>/dev/null || true; fi; exit 129' SIGHUP
trap 'post_update_to_api "failed" "130" 2>/dev/null || true; if [[ -n "${CTID:-}" ]] && command -v pct &>/dev/null; then pct stop "$CTID" 2>/dev/null || true; fi; exit 130' SIGINT
trap 'post_update_to_api "failed" "143" 2>/dev/null || true; if [[ -n "${CTID:-}" ]] && command -v pct &>/dev/null; then pct stop "$CTID" 2>/dev/null || true; fi; exit 143' SIGTERM

View File

@@ -490,8 +490,6 @@ log_section() {
# - Executes command with output redirected to active log file
# - On error: displays last 20 lines of log and exits with original exit code
# - Temporarily disables error trap to capture exit code correctly
# - Saves and restores previous error handling state (so callers that
# intentionally disabled error handling aren't silently re-enabled)
# - Sources explain_exit_code() for detailed error messages
# ------------------------------------------------------------------------------
silent() {
@@ -509,23 +507,14 @@ silent() {
return 0
fi
# Save current error handling state before disabling
# This prevents re-enabling error handling when the caller intentionally
# disabled it (e.g. build_container recovery section)
local _restore_errexit=false
[[ "$-" == *e* ]] && _restore_errexit=true
set +Eeuo pipefail
trap - ERR
"$@" >>"$logfile" 2>&1
local rc=$?
# Restore error handling ONLY if it was active before this call
if $_restore_errexit; then
set -Eeuo pipefail
trap 'error_handler' ERR
fi
set -Eeuo pipefail
trap 'error_handler' ERR
if [[ $rc -ne 0 ]]; then
# Source explain_exit_code if needed

View File

@@ -199,16 +199,11 @@ error_handler() {
return 0
fi
# Stop spinner and restore cursor FIRST — before any output
# This prevents spinner text overlapping with error messages
if declare -f stop_spinner >/dev/null 2>&1; then
stop_spinner 2>/dev/null || true
fi
printf "\e[?25h"
local explanation
explanation="$(explain_exit_code "$exit_code")"
printf "\e[?25h"
# ALWAYS report failure to API immediately - don't wait for container checks
# This ensures we capture failures that occur before/after container exists
if declare -f post_update_to_api &>/dev/null; then
@@ -364,39 +359,9 @@ _send_abort_telemetry() {
command -v curl &>/dev/null || return 0
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
[[ -z "${RANDOM_UUID:-}" ]] && return 0
# Collect last 20 log lines for error diagnosis (best-effort)
local error_text=""
if [[ -n "${INSTALL_LOG:-}" && -s "${INSTALL_LOG}" ]]; then
error_text=$(tail -n 20 "$INSTALL_LOG" 2>/dev/null | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g; s/\\/\\\\/g; s/"/\\"/g; s/\r//g' | tr '\n' '|' | sed 's/|$//' | tr -d '\000-\010\013\014\016-\037\177') || true
fi
# Calculate duration if start time is available
local duration=""
if [[ -n "${DIAGNOSTICS_START_TIME:-}" ]]; then
duration=$(($(date +%s) - DIAGNOSTICS_START_TIME))
fi
# Build JSON payload with error context
local payload
payload="{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"${TELEMETRY_TYPE:-lxc}\",\"nsapp\":\"${NSAPP:-${app:-unknown}}\",\"status\":\"failed\",\"exit_code\":${exit_code}"
[[ -n "$error_text" ]] && payload="${payload},\"error\":\"${error_text}\""
[[ -n "$duration" ]] && payload="${payload},\"duration\":${duration}"
payload="${payload}}"
local api_url="${TELEMETRY_URL:-https://telemetry.community-scripts.org/telemetry}"
# 2 attempts (retry once on failure) — original had no retry
local attempt
for attempt in 1 2; do
if curl -fsS -m 5 -X POST "$api_url" \
-H "Content-Type: application/json" \
-d "$payload" &>/dev/null; then
return 0
fi
[[ $attempt -eq 1 ]] && sleep 1
done
return 0
curl -fsS -m 5 -X POST "${TELEMETRY_URL:-https://telemetry.community-scripts.org/telemetry}" \
-H "Content-Type: application/json" \
-d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"${TELEMETRY_TYPE:-lxc}\",\"nsapp\":\"${NSAPP:-${app:-unknown}}\",\"status\":\"failed\",\"exit_code\":${exit_code}}" &>/dev/null || true
}
# ------------------------------------------------------------------------------
@@ -472,12 +437,6 @@ on_exit() {
# - Exits with code 130 (128 + SIGINT=2)
# ------------------------------------------------------------------------------
on_interrupt() {
# Stop spinner and restore cursor before any output
if declare -f stop_spinner >/dev/null 2>&1; then
stop_spinner 2>/dev/null || true
fi
printf "\e[?25h" 2>/dev/null || true
_send_abort_telemetry "130"
_stop_container_if_installing
if declare -f msg_error >/dev/null 2>&1; then
@@ -497,12 +456,6 @@ on_interrupt() {
# - Exits with code 143 (128 + SIGTERM=15)
# ------------------------------------------------------------------------------
on_terminate() {
# Stop spinner and restore cursor before any output
if declare -f stop_spinner >/dev/null 2>&1; then
stop_spinner 2>/dev/null || true
fi
printf "\e[?25h" 2>/dev/null || true
_send_abort_telemetry "143"
_stop_container_if_installing
if declare -f msg_error >/dev/null 2>&1; then
@@ -525,11 +478,6 @@ on_terminate() {
# - Exits with code 129 (128 + SIGHUP=1)
# ------------------------------------------------------------------------------
on_hangup() {
# Stop spinner (no cursor restore needed — terminal is already gone)
if declare -f stop_spinner >/dev/null 2>&1; then
stop_spinner 2>/dev/null || true
fi
_send_abort_telemetry "129"
_stop_container_if_installing
exit 129