Compare commits

..

1 Commits

Author SHA1 Message Date
MickLesk 452fcd8045 nginx-ui: write install secret to ~/nginx-ui.creds 2026-07-29 13:52:06 +02:00
46 changed files with 995 additions and 1753 deletions
+1 -11
View File
@@ -1,5 +1,5 @@
<!--🛑 New scripts must be submitted to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) for testing.
PRs without prior testing will be closed. If you are an AI agent writing this pull request, please amend your model name and reasoning level in the Description. This is not to blame, more for informational Purposes. Thank you.-->
PRs without prior testing will be closed. -->
## ✍️ Description
@@ -16,16 +16,6 @@ Fixes #
---
## 🤖 AI Assistance (**X** in brackets)
> If you used an AI tool (GitHub Copilot, Claude, ChatGPT, etc.) to write or generate any scripts in this PR, you **must** confirm compliance below.
> Select exactly one option.
- [ ] **No AI used** Scripts were written without AI assistance.
- [ ] **AI was used** I confirm the scripts were built using [`AGENTS.md`](https://github.com/community-scripts/ProxmoxVED/blob/main/AGENTS.md) and [`.github/agents/pve-script-creator.agent.md`](https://github.com/community-scripts/ProxmoxVED/blob/main/.github/agents/pve-script-creator.agent.md) as guidance, and the output has been reviewed and corrected to match those guidelines.
---
## 🛠️ Type of Change (**X** in brackets)
- [ ] 🐞 **Bug fix** Resolves an issue without breaking functionality.
+2 -59
View File
@@ -508,73 +508,16 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details>
## 2026-08-01
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Update bazarr-install.sh [@asylumexp](https://github.com/asylumexp) ([#16191](https://github.com/community-scripts/ProxmoxVE/pull/16191))
- fix romm missing 7z [@asylumexp](https://github.com/asylumexp) ([#16194](https://github.com/community-scripts/ProxmoxVE/pull/16194))
- #### 🔧 Refactor
- add CLEANUPARR_CONFIG_PATH, CLEANUPARR_LOGS_PATH vars [@asylumexp](https://github.com/asylumexp) ([#16193](https://github.com/community-scripts/ProxmoxVE/pull/16193))
## 2026-07-31
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Docmost: cleanup folder at update [@MickLesk](https://github.com/MickLesk) ([#16177](https://github.com/community-scripts/ProxmoxVE/pull/16177))
- Firecrawl: Add dependency [@tremor021](https://github.com/tremor021) ([#16174](https://github.com/community-scripts/ProxmoxVE/pull/16174))
## 2026-07-30
### 🆕 New Scripts
- Firecrawl ([#16156](https://github.com/community-scripts/ProxmoxVE/pull/16156))
- OmniRoute ([#16155](https://github.com/community-scripts/ProxmoxVE/pull/16155))
- PegaProx ([#16154](https://github.com/community-scripts/ProxmoxVE/pull/16154))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Immich: Pin version to 3.1.0 [@vhsdream](https://github.com/vhsdream) ([#16170](https://github.com/community-scripts/ProxmoxVE/pull/16170))
- romm: remove stale 1.x alembic migrations on update [@Darkatek7](https://github.com/Darkatek7) ([#16101](https://github.com/community-scripts/ProxmoxVE/pull/16101))
- #### 🔧 Refactor
- Medusa: convert the non-free unrar source to deb822 format [@angusmaul](https://github.com/angusmaul) ([#16093](https://github.com/community-scripts/ProxmoxVE/pull/16093))
### 💾 Core
- #### ✨ New Features
- tools.func: support dynamic gitlab URL | add setup_mysql_db function [@MickLesk](https://github.com/MickLesk) ([#16166](https://github.com/community-scripts/ProxmoxVE/pull/16166))
- core: add configurable host CA inheritance during bootstrap [@MickLesk](https://github.com/MickLesk) ([#15889](https://github.com/community-scripts/ProxmoxVE/pull/15889))
## 2026-07-29
### 🚀 Updated Scripts
- backup virtual printer in bambuddy [@asylumexp](https://github.com/asylumexp) ([#16142](https://github.com/community-scripts/ProxmoxVE/pull/16142))
- #### 🐞 Bug Fixes
- backup virtual printer in bambuddy [@asylumexp](https://github.com/asylumexp) ([#16142](https://github.com/community-scripts/ProxmoxVE/pull/16142))
- ImmichFrame: check .NET SDK before update deployment [@aidaskni](https://github.com/aidaskni) ([#16104](https://github.com/community-scripts/ProxmoxVE/pull/16104))
- #### ✨ New Features
- Bichon: Migration for V2 Release [@MickLesk](https://github.com/MickLesk) ([#16145](https://github.com/community-scripts/ProxmoxVE/pull/16145))
### 💾 Core
- #### ✨ New Features
- core: Harden remote func bootstrapping with dns issues [@MickLesk](https://github.com/MickLesk) ([#16146](https://github.com/community-scripts/ProxmoxVE/pull/16146))
## 2026-07-28
### 🚀 Updated Scripts
+47 -33
View File
@@ -34,27 +34,30 @@ function update_script() {
CURRENT_VERSION=$(cat /root/.bichon)
fi
if [[ $CURRENT_VERSION != 1.* && $CURRENT_VERSION != 2.* ]]; then
msg_error "Installed ${APP} version (${CURRENT_VERSION}) is too old for an automatic update to v2.x."
msg_error "Please create a new ${APP} container and migrate your data manually."
msg_error "Guide: https://github.com/rustmailer/bichon/wiki/Bichon-v2.x-Migration-Guide"
exit
fi
MIGRATE_V2=0
if [[ $CURRENT_VERSION == 1.* ]]; then
MIGRATE_V2=1
STORAGE_KB=$(du -sk /opt/bichon-data/bichon-storage 2>/dev/null | awk '{print $1}')
FREE_KB=$(df -Pk /opt/bichon-data | awk 'NR==2 {print $4}')
if [[ -n "$STORAGE_KB" && -n "$FREE_KB" && "$FREE_KB" -lt "$STORAGE_KB" ]]; then
echo -e "\n${RD}Warning: migration needs about $((STORAGE_KB / 1024))MB, only $((FREE_KB / 1024))MB free.${CL}"
echo -e "${RD}The new bichon-blob store is written alongside the existing fjall data.${CL}"
MIGRATE_V1=0
if [[ $CURRENT_VERSION == 0.* ]]; then
MIGRATE_V1=1
DISK_USAGE=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$DISK_USAGE" -gt 50 ]; then
echo -e "\n${RD}Warning: Less than 50% free storage remaining on the root disk.${CL}"
echo -e "${RD}Bichon v1 data migration temporarily duplicates data and requires free space for it.${CL}"
read -r -p "Are you sure you want to proceed with the update? (y/N): " proceed
if [[ ! $proceed =~ ^[Yy]$ ]]; then
msg_error "Update cancelled by user."
exit
fi
fi
RAM_TOTAL=$(free -m | awk '/^Mem:/{print $2}')
if [ "$RAM_TOTAL" -lt 2000 ]; then
echo -e "\n${RD}Warning: LXC has less than 2GB of RAM allocated (${RAM_TOTAL}MB).${CL}"
echo -e "${RD}Bichon v1 data migration consumes significant memory and may crash if insufficient.${CL}"
read -r -p "Are you sure you want to proceed with the update? (y/N): " proceed_ram
if [[ ! $proceed_ram =~ ^[Yy]$ ]]; then
msg_error "Update cancelled by user."
exit
fi
fi
fi
if check_for_gh_release "bichon" "rustmailer/bichon"; then
@@ -64,44 +67,55 @@ function update_script() {
create_backup /opt/bichon/bichon.env
if [ "$MIGRATE_V1" -eq 1 ] && [ "$CURRENT_VERSION" != "0.3.7" ]; then
msg_info "Updating to intermediate version v0.3.7"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "bichon" "rustmailer/bichon" "prebuild" "v0.3.7" "/opt/bichon" "bichon-*-$(arch_resolve "x86_64" "aarch64")-unknown-linux-gnu.tar.gz"
restore_backup
systemctl start bichon
sleep 30
systemctl stop bichon
msg_ok "Intermediate update completed"
fi
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "bichon" "rustmailer/bichon" "prebuild" "latest" "/opt/bichon" "bichon-*-$(arch_resolve "x86_64" "aarch64")-unknown-linux-gnu.tar.gz"
restore_backup
if [ "$MIGRATE_V2" -eq 1 ]; then
msg_info "Migrating storage from fjall to bichon-blob (patience)"
if [ "$MIGRATE_V1" -eq 1 ]; then
msg_info "Running Bichon v1 Data Migration (patience)"
$STD apt install -y expect
# Menu: 0 Reset Password, 1 Migrate v0.3.7, 2 Migrate v1.x, 3 Exit
$STD expect <<'EOF'
set timeout -1
spawn /opt/bichon/bichon-admin
expect "*Select an operation*"
send "\033\[B\033\[B\r"
send "\033\[B\r"
expect "*--bichon-root-dir*"
send "/opt/bichon-data\r"
expect "*--bichon-index-dir*"
send "\r"
expect "*--bichon-data-dir*"
send "\r"
expect "*batch size*"
expect "*Ready to migrate?*"
send "y"
expect "*Enter batch size*"
send "1000\r"
expect eof
catch wait
EOF
$STD apt remove --purge expect -y
$STD apt autoremove -y
msg_ok "Migration completed"
if [[ ! -d /opt/bichon-data/bichon-storage/blobs ]] ||
[[ "$(cat /opt/bichon-data/STORAGE_VERSION 2>/dev/null)" != "2" ]]; then
msg_error "Storage migration did not complete - service left stopped, legacy data untouched."
msg_error "Run /opt/bichon/bichon-admin manually and select 'Migrate v1.x Storage to v2.x'."
exit
fi
msg_ok "Migrated storage to bichon-blob"
msg_info "Cleaning up legacy Bichon v0.x storage files"
rm -rf /opt/bichon-data/envelope
rm -rf /opt/bichon-data/eml
rm -f /opt/bichon-data/mailbox.db
rm -f /opt/bichon-data/meta.db
msg_ok "Cleanup completed"
msg_info "Removing legacy fjall files"
rm -rf /opt/bichon-data/bichon-storage/keyspaces
rm -f /opt/bichon-data/bichon-storage/0.jnl
rm -f /opt/bichon-data/bichon-storage/lock
rm -f /opt/bichon-data/bichon-storage/version
msg_ok "Removed legacy fjall files"
msg_info "Updating Bichon service for v1"
sed -i 's|ExecStart=/opt/bichon/bichon|ExecStart=/opt/bichon/bichon-server|g; s|RestartSec=5|RestartSec=5\n\nLimitNOFILE=65536|g' /etc/systemd/system/bichon.service
systemctl daemon-reload
msg_ok "Service updated"
fi
msg_info "Starting service"
+1 -13
View File
@@ -33,19 +33,7 @@ function update_script() {
systemctl stop cleanuparr
msg_ok "Stopped Service"
if [[ ! -d /etc/cleanuparr ]]; then
msg_info "Migrating Configuration to /etc/cleanuparr"
mv /opt/cleanuparr/config /etc/cleanuparr
mkdir -p /etc/cleanuparr /var/log/cleanuparr
rm -rf /etc/cleanuparr/logs
sed -i -e 's|^Environment="CONFIG_DIR=.*|Environment="CLEANUPARR_CONFIG_PATH=/etc/cleanuparr"|' \
-e '/^Environment="CLEANUPARR_CONFIG_PATH=/a Environment="CLEANUPARR_LOGS_PATH=/var/log/cleanuparr"' \
/etc/systemd/system/cleanuparr.service
systemctl daemon-reload
msg_ok "Migrated Configuration to /etc/cleanuparr"
fi
create_backup /etc/cleanuparr
create_backup /opt/cleanuparr/config
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Cleanuparr" "Cleanuparr/Cleanuparr" "prebuild" "latest" "/opt/cleanuparr" "*linux-$(arch_resolve).zip"
+3 -3
View File
@@ -37,9 +37,9 @@ function update_script() {
systemctl stop docmost
msg_ok "Stopped Service"
create_backup /opt/docmost/.env /opt/docmost/data
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "docmost" "docmost/docmost" "tarball"
create_backup /opt/docmost/.env \
/opt/docmost/data
fetch_and_deploy_gh_release "docmost" "docmost/docmost" "tarball"
restore_backup
-93
View File
@@ -1,93 +0,0 @@
#!/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: esatbayhan
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.firecrawl.dev/
APP="Firecrawl"
var_tags="${var_tags:-scraping;ai;crawler}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-30}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-no}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/firecrawl/apps/api ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
ensure_dependencies build-essential
if check_for_gh_release "firecrawl" "firecrawl/firecrawl"; then
msg_info "Stopping Services"
systemctl stop firecrawl firecrawl-playwright
msg_ok "Stopped Services"
create_backup /opt/firecrawl/.env
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "firecrawl" "firecrawl/firecrawl" "tarball" "latest" "/opt/firecrawl"
restore_backup
FDB_VERSION="$(awk -F= '/^ARG FDB_VERSION=/{print $2; exit}' /opt/firecrawl/apps/api/Dockerfile)"
if [[ -z "$FDB_VERSION" ]]; then
msg_error "FDB_VERSION pin not found in upstream Dockerfile"
exit 1
fi
if [[ "$(dpkg-query -W -f='${Version}' foundationdb-clients 2>/dev/null)" != "${FDB_VERSION}-"* ]]; then
FDB_ARCH="$(get_system_arch)"
[[ "$FDB_ARCH" == "arm64" ]] && FDB_ARCH="aarch64"
fetch_and_deploy_gh_release "foundationdb-clients" "apple/foundationdb" "binary" "$FDB_VERSION" "/opt/foundationdb-clients" "foundationdb-clients_${FDB_VERSION}-1_${FDB_ARCH}.deb"
fi
msg_info "Building Go Library"
cd /opt/firecrawl/apps/api/sharedLibs/go-html-to-md
$STD go build -o libhtml-to-markdown.so -buildmode=c-shared html-to-markdown.go
msg_ok "Built Go Library"
msg_info "Building Firecrawl API"
source "$HOME/.cargo/env"
cd /opt/firecrawl/apps/api
$STD pnpm install --frozen-lockfile
$STD pnpm build
CI=true $STD pnpm prune --prod --ignore-scripts
msg_ok "Built Firecrawl API"
msg_info "Building Playwright Service"
cd /opt/firecrawl/apps/playwright-service-ts
$STD npm install
$STD npx playwright install chromium --with-deps
$STD npm run build
$STD npm prune --omit=dev
msg_ok "Built Playwright Service"
msg_info "Starting Services"
systemctl start firecrawl-playwright firecrawl
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}http://${IP}:3002${CL}"
-6
View File
@@ -1,6 +0,0 @@
_______ __
/ ____(_)_______ ______________ __ __/ /
/ /_ / / ___/ _ \/ ___/ ___/ __ `/ | /| / / /
/ __/ / / / / __/ /__/ / / /_/ /| |/ |/ / /
/_/ /_/_/ \___/\___/_/ \__,_/ |__/|__/_/
-6
View File
@@ -1,6 +0,0 @@
____ _ ____ __
/ __ \____ ___ ____ (_) __ \____ __ __/ /____
/ / / / __ `__ \/ __ \/ / /_/ / __ \/ / / / __/ _ \
/ /_/ / / / / / / / / / / _, _/ /_/ / /_/ / /_/ __/
\____/_/ /_/ /_/_/ /_/_/_/ |_|\____/\__,_/\__/\___/
-6
View File
@@ -1,6 +0,0 @@
____ ____
/ __ \___ ____ _____ _/ __ \_________ _ __
/ /_/ / _ \/ __ `/ __ `/ /_/ / ___/ __ \| |/_/
/ ____/ __/ /_/ / /_/ / ____/ / / /_/ /> <
/_/ \___/\__, /\__,_/_/ /_/ \____/_/|_|
/____/
+1 -2
View File
@@ -110,7 +110,7 @@ EOF
msg_ok "Image-processing libraries up to date"
fi
RELEASE="v3.1.0"
RELEASE="v3.0.3"
if check_for_gh_release "Immich" "immich-app/immich" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
if [[ $(cat ~/.immich) > "2.5.1" ]]; then
msg_info "Enabling Maintenance Mode"
@@ -310,7 +310,6 @@ EOF
grep -rl /usr/src | xargs -n1 sed -i "s|\/usr/src|$INSTALL_DIR|g"
grep -rlE "'/build'" | xargs -n1 sed -i "s|'/build'|'$APP_DIR'|g"
sed -i "s@\"/cache\"@\"$INSTALL_DIR/cache\"@g" "$ML_DIR"/immich_ml/config.py
[[ ! -f "$GEO_DIR/countryInfo.txt" ]] && curl_with_retry "https://download.geonames.org/export/dump/countryInfo.txt" "countryInfo.txt"
ln -s "${UPLOAD_DIR:-/opt/immich/upload}" "$APP_DIR"/upload
ln -s "${UPLOAD_DIR:-/opt/immich/upload}" "$ML_DIR"/upload
ln -s "$GEO_DIR" "$APP_DIR"
-69
View File
@@ -1,69 +0,0 @@
#!/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: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/diegosouzapw/OmniRoute
APP="OmniRoute"
var_tags="${var_tags:-ai;gateway;llm}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-no}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/omniroute ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Checking for Updates"
local LATEST
LATEST=$(npm view omniroute version 2>/dev/null)
if [[ -z "$LATEST" ]]; then
msg_error "Could not determine latest OmniRoute version"
exit
fi
if [[ "$LATEST" == "$(omniroute --version 2>/dev/null)" ]]; then
msg_ok "Already up to date (${LATEST})"
exit
fi
msg_ok "New version available: ${LATEST}"
msg_info "Stopping Service"
systemctl stop omniroute
msg_ok "Stopped Service"
msg_info "Updating OmniRoute to ${LATEST}"
$STD npm install -g omniroute@latest
msg_ok "Updated OmniRoute to ${LATEST}"
msg_info "Starting Service"
systemctl start omniroute
msg_ok "Started Service"
msg_ok "Updated successfully!"
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 "${TAB}${GATEWAY}${BGN}http://${IP}:20128${CL}"
echo -e "${INFO}${YW} The admin password is stored in /opt/omniroute/.env (INITIAL_PASSWORD)${CL}"
-64
View File
@@ -1,64 +0,0 @@
#!/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: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/PegaProx/project-pegaprox
APP="PegaProx"
var_tags="${var_tags:-proxmox;management}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-no}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/pegaprox ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "pegaprox" "PegaProx/project-pegaprox"; then
msg_info "Stopping Service"
systemctl stop pegaprox
msg_ok "Stopped Service"
create_backup /opt/pegaprox/config /etc/pegaprox/secret.key
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pegaprox" "PegaProx/project-pegaprox" "tarball"
msg_info "Updating Python Environment"
$STD uv venv --python 3.12 /opt/pegaprox/venv
$STD uv pip install --python /opt/pegaprox/venv/bin/python -r /opt/pegaprox/requirements.txt
msg_ok "Updated Python Environment"
restore_backup
msg_info "Starting Service"
systemctl start pegaprox
msg_ok "Started Service"
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 "${TAB}${GATEWAY}${BGN}https://${IP}:5000${CL}"
-10
View File
@@ -30,12 +30,6 @@ function update_script() {
exit
fi
if [[ ! -x /usr/bin/7zz || ! -x /usr/bin/bsdtar ]]; then
msg_info "Installing Archive Tools"
$STD apt install -y 7zip-standalone libarchive-tools
msg_ok "Installed Archive Tools"
fi
NODE_VERSION="24" setup_nodejs
if check_for_gh_release "romm" "rommapp/romm"; then
@@ -50,10 +44,6 @@ function update_script() {
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "romm" "rommapp/romm" "tarball" "latest" "/opt/romm"
find /opt/romm/backend/alembic/versions -maxdepth 1 -type f -name '1.*.py' -delete 2>/dev/null || true
find /opt/romm/backend/alembic/versions -maxdepth 1 -type f -name '2.0.0_.py' -delete 2>/dev/null || true
find /opt/romm/backend -name '__pycache__' -type d -prune -exec rm -rf {} + 2>/dev/null || true
restore_backup
msg_info "Updating ROMM"
-1
View File
@@ -22,7 +22,6 @@ chmod 775 /opt/bazarr /var/lib/bazarr/
sed -i.bak 's/--only-binary=Pillow//g' /opt/bazarr/requirements.txt
$STD uv venv --clear /opt/bazarr/venv --python 3.12
$STD uv pip install -r /opt/bazarr/requirements.txt --python /opt/bazarr/venv/bin/python3
$STD uv pip install psycopg2-binary --python /opt/bazarr/venv/bin/python3
msg_ok "Installed Bazarr"
msg_info "Creating Service"
+1 -1
View File
@@ -60,7 +60,7 @@ LimitNOFILE=65536
WantedBy=multi-user.target
EOF
systemctl enable -q --now bichon
msg_ok "Created Service"
msg_info "Created Service"
motd_ssh
customize
+1 -3
View File
@@ -16,7 +16,6 @@ update_os
fetch_and_deploy_gh_release "Cleanuparr" "Cleanuparr/Cleanuparr" "prebuild" "latest" "/opt/cleanuparr" "*linux-$(arch_resolve).zip"
msg_info "Creating Service"
mkdir -p /etc/cleanuparr /var/log/cleanuparr
cat <<EOF >/etc/systemd/system/cleanuparr.service
[Unit]
Description=Cleanuparr Daemon
@@ -30,8 +29,7 @@ ExecStart=/opt/cleanuparr/Cleanuparr
Restart=on-failure
RestartSec=5
Environment="PORT=11011"
Environment="CLEANUPARR_CONFIG_PATH=/etc/cleanuparr"
Environment="CLEANUPARR_LOGS_PATH=/var/log/cleanuparr"
Environment="CONFIG_DIR=/opt/cleanuparr/config"
[Install]
WantedBy=multi-user.target
-230
View File
@@ -1,230 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: esatbayhan
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.firecrawl.dev/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
cmake \
git \
nftables \
pkg-config \
procps \
python3 \
rabbitmq-server \
redis-server
msg_ok "Installed Dependencies"
NODE_VERSION="22" NODE_MODULE="pnpm@11.4.0" setup_nodejs
setup_go
RUST_PROFILE="minimal" setup_rust
PG_VERSION="17" PG_MODULES="cron" setup_postgresql
fetch_and_deploy_gh_release "firecrawl" "firecrawl/firecrawl" "tarball" "latest" "/opt/firecrawl"
msg_info "Configuring FDB"
FDB_VERSION="$(awk -F= '/^ARG FDB_VERSION=/{print $2; exit}' /opt/firecrawl/apps/api/Dockerfile)"
if [[ -z "$FDB_VERSION" ]]; then
msg_error "FDB_VERSION pin not found in upstream Dockerfile"
exit 1
fi
FDB_ARCH="$(get_system_arch)"
[[ "$FDB_ARCH" == "arm64" ]] && FDB_ARCH="aarch64"
fetch_and_deploy_gh_release "foundationdb-clients" "apple/foundationdb" "binary" "$FDB_VERSION" "/opt/foundationdb-clients" "foundationdb-clients_${FDB_VERSION}-1_${FDB_ARCH}.deb"
msg_ok "Configured FDB"
PG_DB_NAME="firecrawl" PG_DB_USER="firecrawl" PG_DB_EXTENSIONS="pgcrypto,pg_cron" PG_DB_CREDS_FILE="/dev/null" setup_postgresql_db
msg_info "Configuring pg_cron"
$STD runuser -u postgres -- psql -c "ALTER SYSTEM SET cron.use_background_workers = 'on';"
systemctl restart postgresql
until runuser -u postgres -- psql -c "SELECT 1;" &>/dev/null; do sleep 1; done
msg_ok "Configured pg_cron"
msg_info "Configuring RabbitMQ"
systemctl enable -q --now rabbitmq-server
until rabbitmqctl status &>/dev/null; do sleep 1; done
RABBITMQ_PASSWORD="$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c24)"
$STD rabbitmqctl add_user firecrawl "$RABBITMQ_PASSWORD"
$STD rabbitmqctl set_permissions -p / firecrawl ".*" ".*" ".*"
msg_ok "Configured RabbitMQ"
systemctl enable -q --now redis-server
msg_info "Importing NuQ Schema"
$STD runuser -u postgres -- psql -d firecrawl -f /opt/firecrawl/apps/nuq-postgres/nuq.sql
$STD runuser -u postgres -- psql -d firecrawl -c "GRANT USAGE ON SCHEMA nuq TO firecrawl;"
$STD runuser -u postgres -- psql -d firecrawl -c "GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA nuq TO firecrawl;"
$STD runuser -u postgres -- psql -d firecrawl -c "GRANT USAGE, SELECT, UPDATE ON ALL SEQUENCES IN SCHEMA nuq TO firecrawl;"
$STD runuser -u postgres -- psql -d firecrawl -c "ALTER DEFAULT PRIVILEGES IN SCHEMA nuq GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO firecrawl;"
$STD runuser -u postgres -- psql -d firecrawl -c "ALTER DEFAULT PRIVILEGES IN SCHEMA nuq GRANT USAGE, SELECT, UPDATE ON SEQUENCES TO firecrawl;"
msg_ok "Imported NuQ Schema"
msg_info "Generating Configuration"
cat <<EOF >/opt/firecrawl/.env
ENV=local
HOST=0.0.0.0
PORT=3002
USE_DB_AUTHENTICATION=false
BULL_AUTH_KEY=$(openssl rand -hex 32)
JWT_SECRET=$(openssl rand -hex 32)
REDIS_URL=redis://127.0.0.1:6379
REDIS_RATE_LIMIT_URL=redis://127.0.0.1:6379
PLAYWRIGHT_MICROSERVICE_URL=http://127.0.0.1:3000/scrape
POSTGRES_HOST=127.0.0.1
POSTGRES_PORT=5432
POSTGRES_USER=${PG_DB_USER}
POSTGRES_PASSWORD=${PG_DB_PASS}
POSTGRES_DB=${PG_DB_NAME}
NUQ_DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@127.0.0.1:5432/${PG_DB_NAME}
NUQ_DATABASE_URL_LISTEN=postgresql://${PG_DB_USER}:${PG_DB_PASS}@127.0.0.1:5432/${PG_DB_NAME}
NUQ_BACKEND=pg
NUQ_RABBITMQ_URL=amqp://firecrawl:${RABBITMQ_PASSWORD}@127.0.0.1:5672/%2f
WORKER_PORT=3005
EXTRACT_WORKER_PORT=3004
NUQ_WORKER_START_PORT=3006
NUQ_WORKER_COUNT=5
NUQ_PREFETCH_WORKER_PORT=3011
NUQ_RECONCILER_WORKER_PORT=3012
HARNESS_STARTUP_TIMEOUT_MS=60000
LOGGING_LEVEL=INFO
MAX_CONCURRENT_PAGES=10
ALLOW_LOCAL_WEBHOOKS=false
BLOCK_MEDIA=false
OPENAI_API_KEY=
OPENAI_BASE_URL=
OLLAMA_BASE_URL=
MODEL_NAME=
MODEL_EMBEDDING_NAME=
SEARXNG_ENDPOINT=
SEARXNG_ENGINES=
SEARXNG_CATEGORIES=
PROXY_SERVER=
PROXY_USERNAME=
PROXY_PASSWORD=
SELF_HOSTED_WEBHOOK_URL=
SELF_HOSTED_WEBHOOK_HMAC_SECRET=
EOF
chmod 600 /opt/firecrawl/.env
msg_ok "Generated Configuration"
msg_info "Building Go Library"
cd /opt/firecrawl/apps/api/sharedLibs/go-html-to-md
$STD go build -o libhtml-to-markdown.so -buildmode=c-shared html-to-markdown.go
msg_ok "Built Go Library"
msg_info "Building Firecrawl API"
cd /opt/firecrawl/apps/api
$STD pnpm install --frozen-lockfile
$STD pnpm build
CI=true $STD pnpm prune --prod --ignore-scripts
msg_ok "Built Firecrawl API"
msg_info "Building Playwright Service"
cd /opt/firecrawl/apps/playwright-service-ts
$STD npm install
$STD npx playwright install chromium --with-deps
$STD npm run build
$STD npm prune --omit=dev
msg_ok "Built Playwright Service"
msg_info "Creating Services"
cat <<EOF >/etc/systemd/system/firecrawl-playwright.service
[Unit]
Description=Firecrawl Playwright Service
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/firecrawl/apps/playwright-service-ts
EnvironmentFile=/opt/firecrawl/.env
Environment=PORT=3000
# /opt/firecrawl/.env also contains the API PORT=3002; force Playwright's private port here.
ExecStart=/usr/bin/env PORT=3000 /usr/bin/node /opt/firecrawl/apps/playwright-service-ts/dist/api.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/firecrawl.service
[Unit]
Description=Firecrawl API and Workers
After=network.target postgresql.service redis-server.service rabbitmq-server.service firecrawl-playwright.service
Requires=postgresql.service redis-server.service rabbitmq-server.service firecrawl-playwright.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/firecrawl/apps/api
EnvironmentFile=/opt/firecrawl/.env
Environment=NODE_ENV=production
# Upstream uses --start-docker to skip install/build and start compiled node dist entrypoints.
ExecStart=/usr/bin/node /opt/firecrawl/apps/api/dist/src/harness.js --start-docker
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now firecrawl-playwright
systemctl enable -q --now firecrawl
msg_ok "Created Services"
msg_info "Configuring Firewall"
cat <<'EOF' >/etc/nftables.conf
#!/usr/sbin/nft -f
flush ruleset
table inet firecrawl_filter {
chain input {
type filter hook input priority 0; policy drop;
iif "lo" accept
ct state established,related accept
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
udp sport 67 udp dport 68 accept
udp sport 547 udp dport 546 accept
tcp dport { 22, 3002 } accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
EOF
systemctl enable -q nftables
systemctl restart nftables
msg_ok "Configured Firewall"
motd_ssh
customize
cleanup_lxc
+1 -2
View File
@@ -312,7 +312,7 @@ ML_DIR="${APP_DIR}/machine-learning"
GEO_DIR="${INSTALL_DIR}/geodata"
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
fetch_and_deploy_gh_release "Immich" "immich-app/immich" "tarball" "v3.1.0" "$SRC_DIR"
fetch_and_deploy_gh_release "Immich" "immich-app/immich" "tarball" "v3.0.3" "$SRC_DIR"
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1] | split("+")[0]' ${SRC_DIR}/package.json)"
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs
@@ -429,7 +429,6 @@ msg_info "Installing GeoNames data"
cd "$GEO_DIR"
curl_with_retry "https://download.geonames.org/export/dump/admin1CodesASCII.txt" "admin1CodesASCII.txt"
curl_with_retry "https://download.geonames.org/export/dump/admin2Codes.txt" "admin2Codes.txt"
curl_with_retry "https://download.geonames.org/export/dump/countryInfo.txt" "countryInfo.txt"
curl_with_retry "https://download.geonames.org/export/dump/cities500.zip" "cities500.zip"
curl_with_retry "https://raw.githubusercontent.com/nvkelso/natural-earth-vector/v5.1.2/geojson/ne_10m_admin_0_countries.geojson" "ne_10m_admin_0_countries.geojson"
unzip -q cities500.zip
+3 -7
View File
@@ -19,16 +19,12 @@ $STD apt install -y \
git-core \
mediainfo
cat <<EOF >/etc/apt/sources.list.d/non-free.sources
Types: deb
URIs: https://deb.debian.org/debian
Suites: trixie
Components: non-free non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
cat <<EOF >/etc/apt/sources.list.d/non-free.list
deb https://deb.debian.org/debian trixie main contrib non-free non-free-firmware
EOF
$STD apt update
$STD apt install -y unrar
rm /etc/apt/sources.list.d/non-free.sources
rm /etc/apt/sources.list.d/non-free.list
msg_ok "Installed Dependencies"
msg_info "Installing Medusa"
+6
View File
@@ -71,6 +71,12 @@ msg_ok "Created Service"
msg_info "Starting Service"
systemctl enable -q --now nginx-ui
rm -rf /etc/nginx/sites-enabled/default
sleep 3
cat <<EOF >~/nginx-ui.creds
Nginx UI Install Secret: $(cat /usr/local/etc/nginx-ui/.install_secret 2>/dev/null)
Valid for 10 minutes after service start, then removed.
New secret: systemctl restart nginx-ui && cat /usr/local/etc/nginx-ui/.install_secret
EOF
msg_ok "Started Service"
motd_ssh
-59
View File
@@ -1,59 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/diegosouzapw/OmniRoute
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
NODE_VERSION="24" setup_nodejs
msg_info "Installing OmniRoute"
$STD npm install -g omniroute@latest
msg_ok "Installed OmniRoute"
msg_info "Configuring OmniRoute"
mkdir -p /opt/omniroute
cat <<EOF >/opt/omniroute/.env
JWT_SECRET=$(openssl rand -base64 48)
API_KEY_SECRET=$(openssl rand -hex 32)
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
STORAGE_ENCRYPTION_KEY_VERSION=v1
INITIAL_PASSWORD=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-20)
PORT=20128
OMNIROUTE_SERVER_HOST=0.0.0.0
EOF
chmod 600 /opt/omniroute/.env
msg_ok "Configured OmniRoute"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/omniroute.service
[Unit]
Description=OmniRoute AI Gateway
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/omniroute
Environment=DATA_DIR=/opt/omniroute
ExecStart=/usr/bin/omniroute
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now omniroute
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
-60
View File
@@ -1,60 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/PegaProx/project-pegaprox
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y sshpass
msg_ok "Installed Dependencies"
PYTHON_VERSION="3.12" setup_uv
fetch_and_deploy_gh_release "pegaprox" "PegaProx/project-pegaprox" "tarball"
msg_info "Setting up Python Environment"
$STD uv venv --python 3.12 /opt/pegaprox/venv
$STD uv pip install --python /opt/pegaprox/venv/bin/python -r /opt/pegaprox/requirements.txt
msg_ok "Set up Python Environment"
msg_info "Generating Master Key"
mkdir -p /etc/pegaprox
cat <<EOF >/etc/pegaprox/secret.key
$(openssl rand -base64 32 | tr '+/' '-_')
EOF
chmod 600 /etc/pegaprox/secret.key
msg_ok "Generated Master Key"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/pegaprox.service
[Unit]
Description=PegaProx - Multi-Cluster Proxmox VE Management
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/pegaprox
ExecStart=/opt/pegaprox/venv/bin/python /opt/pegaprox/pegaprox_multi_cluster.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now pegaprox
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
-2
View File
@@ -37,8 +37,6 @@ $STD apt install -y \
redis-server \
redis-tools \
p7zip-full \
7zip-standalone \
libarchive-tools \
tzdata
msg_ok "Installed Dependencies"
+2 -23
View File
@@ -10,29 +10,8 @@ fi
# must write local failure artifacts instead of talking to the telemetry API
# (the host is the single telemetry reporter).
export TELEMETRY_CONTEXT="container"
# A freshly booted container may not have DNS up yet. `source <(curl ...)` hides
# curl's exit code, so a failed download would silently source an empty stream.
_bootstrap_die() {
if declare -f msg_error >/dev/null 2>&1; then
msg_error "$1"
else
echo "FATAL: $1" >&2
fi
exit 115
}
_bootstrap_source() {
local url="$1" probe="$2" content
content=$(curl -fsSL --connect-timeout 10 --retry 5 --retry-connrefused --retry-delay 2 "$url") ||
_bootstrap_die "Failed to download ${url##*/}"
source /dev/stdin <<<"$content"
declare -f "$probe" >/dev/null 2>&1 ||
_bootstrap_die "${url##*/} loaded but incomplete (missing ${probe})"
}
_FUNC_BASE="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc"
_bootstrap_source "$_FUNC_BASE/core.func" load_functions
_bootstrap_source "$_FUNC_BASE/error_handler.func" catch_errors
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
load_functions
catch_errors
+27 -187
View File
@@ -88,38 +88,19 @@ variables() {
fi
}
# `source <(curl ...)` hides the download exit code, so a failed fetch would
# silently source an empty stream and leave the helpers undefined.
_bootstrap_die() {
if declare -f msg_error >/dev/null 2>&1; then
msg_error "$1"
else
echo "FATAL: $1" >&2
fi
exit 115
}
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func)
_bootstrap_source() {
local url="$1" probe="$2" content=""
if command -v curl >/dev/null 2>&1; then
content=$(curl -fsSL --connect-timeout 10 --retry 5 --retry-connrefused --retry-delay 2 "$url") || content=""
elif command -v wget >/dev/null 2>&1; then
content=$(wget -qO- --tries=5 --timeout=10 "$url") || content=""
else
_bootstrap_die "Neither curl nor wget available"
fi
[[ -n "$content" ]] || _bootstrap_die "Failed to download ${url##*/}"
source /dev/stdin <<<"$content"
declare -f "$probe" >/dev/null 2>&1 ||
_bootstrap_die "${url##*/} loaded but incomplete (missing ${probe})"
}
_FUNC_BASE="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc"
_bootstrap_source "$_FUNC_BASE/api.func" post_to_api
_bootstrap_source "$_FUNC_BASE/core.func" load_functions
_bootstrap_source "$_FUNC_BASE/error_handler.func" catch_errors
load_functions
catch_errors
if command -v curl >/dev/null 2>&1; then
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
load_functions
catch_errors
elif command -v wget >/dev/null 2>&1; then
source <(wget -qO- https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(wget -qO- https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
load_functions
catch_errors
fi
# ==============================================================================
# SECTION 2: PRE-FLIGHT CHECKS & SYSTEM VALIDATION
@@ -1130,7 +1111,6 @@ base_settings() {
APT_CACHER=${var_apt_cacher:-""}
APT_CACHER_IP=${var_apt_cacher_ip:-""}
INHERIT_HOST_CA="${var_inherit_host_ca:-no}"
# Runtime check: Verify APT cacher is reachable if configured
if [[ -n "$APT_CACHER_IP" && "$APT_CACHER" == "yes" ]]; then
@@ -1213,7 +1193,7 @@ load_vars_file() {
# Allowed var_* keys
local VAR_WHITELIST=(
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_github_token var_gpu var_http_no_proxy var_http_proxy var_inherit_host_ca var_keyctl
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_github_token var_gpu var_http_no_proxy var_http_proxy var_keyctl
var_gateway var_hostname var_ipv6_method var_mac var_mknod var_mount_fs var_mtu
var_net var_nesting var_ns var_os var_protection var_pw var_ram var_tags var_timezone var_tun var_unprivileged
var_verbose var_version var_vlan var_ssh var_ssh_authorized_key var_container_storage var_template_storage var_searchdomain
@@ -1410,12 +1390,6 @@ load_vars_file() {
continue
fi
;;
var_inherit_host_ca)
if [[ "$var_val" != "yes" && "$var_val" != "no" && "$var_val" != "auto" ]]; then
msg_warn "Invalid host CA inheritance value '$var_val' in $file (must be yes/no/auto), ignoring"
continue
fi
;;
var_container_storage | var_template_storage)
# Validate that the storage exists and is active on the current node
local _storage_status
@@ -1455,7 +1429,7 @@ default_var_settings() {
# Allowed var_* keys (alphabetically sorted)
# Note: Removed var_ctid (can only exist once), var_ipv6_static (static IPs are unique)
local VAR_WHITELIST=(
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_github_token var_gpu var_http_no_proxy var_http_proxy var_inherit_host_ca var_keyctl
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_github_token var_gpu var_http_no_proxy var_http_proxy var_keyctl
var_gateway var_hostname var_ipv6_method var_mac var_mknod var_mount_fs var_mtu
var_net var_nesting var_ns var_os var_protection var_pw var_ram var_tags var_timezone var_tun var_unprivileged
var_verbose var_version var_vlan var_ssh var_ssh_authorized_key var_container_storage var_template_storage
@@ -1538,7 +1512,6 @@ var_ssh=no
# HTTP/HTTPS proxy (optional - for networks requiring a proxy)
# var_http_proxy=http://proxy.local:8080
# var_http_no_proxy=localhost,127.0.0.1,.local
# var_inherit_host_ca=no
# Features/Tags/verbosity
var_fuse=no
@@ -1639,7 +1612,7 @@ get_app_defaults_path() {
if ! declare -p VAR_WHITELIST >/dev/null 2>&1; then
# Note: Removed var_ctid (can only exist once), var_ipv6_static (static IPs are unique)
declare -ag VAR_WHITELIST=(
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_github_token var_gpu var_http_no_proxy var_http_proxy var_inherit_host_ca var_keyctl
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_github_token var_gpu var_http_no_proxy var_http_proxy var_keyctl
var_gateway var_hostname var_ipv6_method var_mac var_mknod var_mount_fs var_mtu
var_net var_nesting var_ns var_os var_protection var_pw var_ram var_tags var_timezone var_tun var_unprivileged
var_verbose var_version var_vlan var_ssh var_ssh_authorized_key var_container_storage var_template_storage var_searchdomain
@@ -1789,7 +1762,6 @@ _build_current_app_vars_tmp() {
_apt_cacher_ip="${APT_CACHER_IP:-}"
_http_proxy="${HTTP_PROXY:-${var_http_proxy:-}}"
_http_no_proxy="${HTTP_NO_PROXY:-${var_http_no_proxy:-}}"
_inherit_host_ca="${INHERIT_HOST_CA:-${var_inherit_host_ca:-no}}"
_fuse="${ENABLE_FUSE:-no}"
_tun="${ENABLE_TUN:-no}"
_gpu="${ENABLE_GPU:-no}"
@@ -1843,7 +1815,6 @@ _build_current_app_vars_tmp() {
[ -n "$_apt_cacher_ip" ] && echo "var_apt_cacher_ip=$(_sanitize_value "$_apt_cacher_ip")"
[ -n "$_http_proxy" ] && echo "var_http_proxy=$(_sanitize_value "$_http_proxy")"
[ -n "$_http_no_proxy" ] && echo "var_http_no_proxy=$(_sanitize_value "$_http_no_proxy")"
[ -n "$_inherit_host_ca" ] && echo "var_inherit_host_ca=$(_sanitize_value "$_inherit_host_ca")"
[ -n "$_fuse" ] && echo "var_fuse=$(_sanitize_value "$_fuse")"
[ -n "$_tun" ] && echo "var_tun=$(_sanitize_value "$_tun")"
@@ -2008,7 +1979,7 @@ advanced_settings() {
TAGS="community-script${var_tags:+;${var_tags}}"
fi
local STEP=1
local MAX_STEP=31
local MAX_STEP=30
# Store values for back navigation - inherit from var_* app defaults
local _ct_type="${var_unprivileged:-1}"
@@ -2030,7 +2001,6 @@ advanced_settings() {
local _apt_cacher_ip="${var_apt_cacher_ip:-}"
local _http_proxy="${var_http_proxy:-}"
local _http_no_proxy="${var_http_no_proxy:-}"
local _inherit_host_ca="${var_inherit_host_ca:-no}"
local _mtu="${var_mtu:-}"
local _sd="${var_searchdomain:-}"
local _ns="${var_ns:-}"
@@ -2860,47 +2830,9 @@ advanced_settings() {
;;
# ═══════════════════════════════════════════════════════════════════════════
# STEP 25: Host CA Inheritance
# STEP 25: Container Timezone
# ═══════════════════════════════════════════════════════════════════════════
25)
local host_ca_count=0
local host_ca_dir="/usr/local/share/ca-certificates"
local cert
shopt -s nullglob
for cert in "$host_ca_dir"/*.crt; do
host_ca_count=$((host_ca_count + 1))
done
shopt -u nullglob
if [[ $host_ca_count -eq 0 ]]; then
_inherit_host_ca="no"
((STEP++))
continue
fi
local host_ca_default_flag="--defaultno"
[[ "$_inherit_host_ca" == "yes" ]] && host_ca_default_flag=""
if whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "HOST CA INHERITANCE" \
--ok-button "Next" --cancel-button "Back" \
$host_ca_default_flag \
--yesno "\nInherit host CA certificates into this container?\n\nDetected on host: ${host_ca_count} certificate(s) in:\n${host_ca_dir}\n\nRecommended for private PKI / TLS-inspection environments.\n\n(App default: ${var_inherit_host_ca:-no})" 16 72; then
_inherit_host_ca="yes"
else
if [ $? -eq 1 ]; then
_inherit_host_ca="no"
else
((STEP--))
continue
fi
fi
((STEP++))
;;
# ═══════════════════════════════════════════════════════════════════════════
# STEP 26: Container Timezone
# ═══════════════════════════════════════════════════════════════════════════
26)
local tz_hint="$_ct_timezone"
[[ -z "$tz_hint" ]] && tz_hint="(empty - will use host timezone)"
@@ -2923,9 +2855,9 @@ advanced_settings() {
;;
# ═══════════════════════════════════════════════════════════════════════════
# STEP 27: Container Protection
# STEP 26: Container Protection
# ═══════════════════════════════════════════════════════════════════════════
27)
26)
local protect_default_flag="--defaultno"
[[ "$_protect_ct" == "yes" || "$_protect_ct" == "1" ]] && protect_default_flag=""
@@ -2947,9 +2879,9 @@ advanced_settings() {
;;
# ═══════════════════════════════════════════════════════════════════════════
# STEP 28: Device Node Creation (mknod)
# STEP 27: Device Node Creation (mknod)
# ═══════════════════════════════════════════════════════════════════════════
28)
27)
local mknod_default_flag="--defaultno"
[[ "$_enable_mknod" == "1" ]] && mknod_default_flag=""
@@ -2971,9 +2903,9 @@ advanced_settings() {
;;
# ═══════════════════════════════════════════════════════════════════════════
# STEP 29: Mount Filesystems
# STEP 28: Mount Filesystems
# ═══════════════════════════════════════════════════════════════════════════
29)
28)
local mount_hint=""
[[ -n "$_mount_fs" ]] && mount_hint="$_mount_fs" || mount_hint="(none)"
@@ -2994,9 +2926,9 @@ advanced_settings() {
;;
# ═══════════════════════════════════════════════════════════════════════════
# STEP 30: Optional host-side post-install hook (path on the Proxmox HOST)
# STEP 29: Optional host-side post-install hook (path on the Proxmox HOST)
# ═══════════════════════════════════════════════════════════════════════════
30)
29)
local _hook_prompt="Optional: absolute path to a *.sh file ON THE PROXMOX HOST.
It runs as root on the HOST (NOT in the LXC) after the container
@@ -3046,9 +2978,9 @@ Leave empty to skip."
;;
# ═══════════════════════════════════════════════════════════════════════════
# STEP 31: Verbose Mode & Confirmation
# STEP 30: Verbose Mode & Confirmation
# ═══════════════════════════════════════════════════════════════════════════
31)
30)
local verbose_default_flag="--defaultno"
[[ "$_verbose" == "yes" ]] && verbose_default_flag=""
@@ -3077,7 +3009,6 @@ Leave empty to skip."
local apt_display="${_apt_cacher:-no}"
[[ "$_apt_cacher" == "yes" && -n "$_apt_cacher_ip" ]] && apt_display="$_apt_cacher_ip"
local http_proxy_display="${_http_proxy:-(none)}"
local inherit_ca_display="${_inherit_host_ca:-no}"
local post_install_display="${_post_install:-(none)}"
local post_install_warn=""
@@ -3108,7 +3039,6 @@ Advanced:
Timezone: $tz_display
APT Cacher: $apt_display
HTTP Proxy: $http_proxy_display
Inherit Host CAs: $inherit_ca_display
Verbose: $_verbose
Post-Install Script: ${post_install_display}${post_install_warn}"
@@ -3154,7 +3084,6 @@ Advanced:
APT_CACHER_IP="$_apt_cacher_ip"
HTTP_PROXY="$_http_proxy"
HTTP_NO_PROXY="$_http_no_proxy"
INHERIT_HOST_CA="$_inherit_host_ca"
VERBOSE="$_verbose"
var_post_install="$_post_install"
@@ -3173,7 +3102,6 @@ Advanced:
var_sdn_vnet="$_sdn_vnet"
var_http_proxy="$_http_proxy"
var_http_no_proxy="$_http_no_proxy"
var_inherit_host_ca="$_inherit_host_ca"
# Format optional values
[[ -n "$_mtu" ]] && MTU=",mtu=$_mtu" || MTU=""
@@ -4213,83 +4141,6 @@ EOF
msg_ok "Applied HTTP proxy in container"
}
# ------------------------------------------------------------------------------
# _apply_host_ca_certs_in_container()
#
# - Copies administrator-provided CA certificates from the Proxmox host into the
# container before base package bootstrap
# - Source: /usr/local/share/ca-certificates/*.crt (Debian convention)
# - Refreshes the container trust store when update-ca-certificates is available
# - No-op when no host certificates are present; failures are non-fatal
# ------------------------------------------------------------------------------
_apply_host_ca_certs_in_container() {
local host_ca_dir="/usr/local/share/ca-certificates"
[[ -z "${CTID:-}" ]] && return 0
local inherit_host_ca="${INHERIT_HOST_CA:-${var_inherit_host_ca:-no}}"
local -a host_certs=()
local cert
shopt -s nullglob
for cert in "$host_ca_dir"/*.crt; do
host_certs+=("$cert")
done
shopt -u nullglob
[[ ${#host_certs[@]} -eq 0 ]] && return 0
# Opt-in only: copy host CA certs solely when explicitly enabled.
# Any other value (no/auto/unset) is a silent no-op to preserve LXC isolation.
case "${inherit_host_ca,,}" in
yes | true | 1 | on) ;;
*)
return 0
;;
esac
msg_info "Inheriting host CA certificates into container"
local found=${#host_certs[@]}
local copied=0
local skipped=0
local cert_name
pct exec "$CTID" -- mkdir -p /usr/local/share/ca-certificates >/dev/null 2>&1 || {
msg_warn "Failed to create CA certificate directory in container"
return 0
}
for cert in "${host_certs[@]}"; do
cert_name="$(basename "$cert")"
if [[ ! -r "$cert" || "$cert_name" != *.crt ]]; then
msg_warn "Skipping invalid or unreadable host CA certificate: ${cert_name}"
skipped=$((skipped + 1))
continue
fi
if pct push "$CTID" "$cert" "/usr/local/share/ca-certificates/${cert_name}" >/dev/null 2>&1; then
pct exec "$CTID" -- chmod 644 "/usr/local/share/ca-certificates/${cert_name}" >/dev/null 2>&1 || true
copied=$((copied + 1))
else
msg_warn "Failed to push host CA certificate: ${cert_name}"
skipped=$((skipped + 1))
fi
done
if [[ $copied -eq 0 ]]; then
msg_warn "No host CA certificates were copied (${found} found, ${skipped} skipped)"
return 0
fi
local refresh_shell="bash"
[[ "$var_os" == "alpine" ]] && refresh_shell="ash"
if pct exec "$CTID" -- "$refresh_shell" -c 'command -v update-ca-certificates >/dev/null 2>&1 && update-ca-certificates' >/dev/null 2>&1; then
msg_ok "Inherited ${copied} host CA certificate(s) and updated trust store (${skipped} skipped)"
else
msg_warn "Copied ${copied} host CA certificate(s), but trust store update failed or update-ca-certificates is unavailable (${skipped} skipped)"
fi
}
# ------------------------------------------------------------------------------
# build_container()
#
@@ -4919,7 +4770,6 @@ EOF
local install_exit_code=0
_apply_http_proxy_in_container
_apply_host_ca_certs_in_container
# Continue with standard container setup
if [ "$var_os" == "alpine" ]; then
@@ -5200,16 +5050,6 @@ EOF
# TSTP = Ctrl+Z, TTIN = bg read from tty, TTOU = bg write to tty (tostop)
trap '' TSTP TTIN TTOU
# lxc-attach takes the controlling terminal while the install runs and does
# not hand it back, leaving us in a background process group. Reading from
# the terminal then returns EIO instead of blocking, because SIGTTIN is
# ignored above - so every recovery prompt fails before the user can answer.
# Redirecting to /dev/tty does not help: the rule applies to the terminal,
# not the file descriptor. Claim the foreground group back; SIGTTOU is
# ignored too, so tcsetpgrp() succeeds instead of stopping us. No-op when we
# already are in the foreground. perl is a hard dependency of Proxmox VE.
perl -e 'use POSIX; open(my $t, "+<", "/dev/tty") or exit 1; POSIX::tcsetpgrp(fileno($t), getpgrp()) or exit 1;' 2>/dev/null || true
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
+2 -23
View File
@@ -37,29 +37,8 @@ fi
# (the host is the single telemetry reporter).
export TELEMETRY_CONTEXT="container"
# A freshly booted container may not have DNS up yet. `source <(curl ...)` hides
# curl's exit code, so a failed download would silently source an empty stream.
_bootstrap_die() {
if declare -f msg_error >/dev/null 2>&1; then
msg_error "$1"
else
echo "FATAL: $1" >&2
fi
exit 115
}
_bootstrap_source() {
local url="$1" probe="$2" content
content=$(curl -fsSL --connect-timeout 10 --retry 5 --retry-connrefused --retry-delay 2 "$url") ||
_bootstrap_die "Failed to download ${url##*/}"
source /dev/stdin <<<"$content"
declare -f "$probe" >/dev/null 2>&1 ||
_bootstrap_die "${url##*/} loaded but incomplete (missing ${probe})"
}
_FUNC_BASE="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc"
_bootstrap_source "$_FUNC_BASE/core.func" load_functions
_bootstrap_source "$_FUNC_BASE/error_handler.func" catch_errors
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
load_functions
catch_errors
+24 -78
View File
@@ -2736,8 +2736,7 @@ get_latest_gl_tag() {
local repo_encoded
repo_encoded=$(printf '%s' "$repo" | sed 's|/|%2F|g')
local gitlab_url="${GITLAB_URL:-https://gitlab.com}"
local api_base="${gitlab_url}/api/v4/projects/${repo_encoded}/repository/tags"
local api_base="https://gitlab.com/api/v4/projects/${repo_encoded}/repository/tags"
local api_timeout="--connect-timeout 10 --max-time 60"
local header=()
@@ -2819,7 +2818,6 @@ get_latest_gl_tag() {
# Notes:
# - Supports CLEAN_INSTALL=1 to wipe target before extracting
# - Supports GITLAB_TOKEN for private/rate-limited projects
# - Supports GITLAB_URL for self-hosted GitLab (default: https://gitlab.com)
# - For repos that only publish tags, not formal GitLab Releases
# (use fetch_and_deploy_gl_release for proper Releases with assets)
# ------------------------------------------------------------------------------
@@ -2863,9 +2861,8 @@ fetch_and_deploy_gl_tag() {
repo_encoded=$(printf '%s' "$repo" | sed 's|/|%2F|g')
# GitLab source tarball URL (no release needed, works for any tag).
local gitlab_url="${GITLAB_URL:-https://gitlab.com}"
local version_safe="${resolved_tag//\//-}"
local tarball_url="${gitlab_url}/${repo}/-/archive/${resolved_tag}/${app_lc}-${version_safe}.tar.gz"
local tarball_url="https://gitlab.com/${repo}/-/archive/${resolved_tag}/${app_lc}-${version_safe}.tar.gz"
local tmpdir
tmpdir=$(mktemp -d) || return 1
@@ -6950,60 +6947,6 @@ setup_mariadb_db() {
export MARIADB_DB_PASS
}
# ------------------------------------------------------------------------------
# Creates a MySQL database and user (for apps that require MySQL, not MariaDB).
#
# Description:
# - Creates database, user and grants using the mysql root socket login
# - The user is created with host '%' because MySQL treats 'localhost'
# (socket) and '127.0.0.1' (TCP) as distinct hosts; apps connecting over
# TCP to 127.0.0.1 would not match a 'localhost' account. mysql-server
# binds to 127.0.0.1 by default, so '%' stays local-only.
#
# Variables:
# MYSQL_DB_NAME - Database name (required)
# MYSQL_DB_USER - Database user (required)
# MYSQL_DB_PASS - Password (optional, generated if unset)
#
# Exports:
# MYSQL_DB_NAME, MYSQL_DB_USER, MYSQL_DB_PASS
#
# Example:
# MYSQL_DB_NAME="fleet" MYSQL_DB_USER="fleet" setup_mysql_db
# ------------------------------------------------------------------------------
setup_mysql_db() {
if [[ -z "${MYSQL_DB_NAME:-}" || -z "${MYSQL_DB_USER:-}" ]]; then
msg_error "MYSQL_DB_NAME and MYSQL_DB_USER must be set before calling setup_mysql_db"
return 65
fi
if [[ -z "${MYSQL_DB_PASS:-}" ]]; then
MYSQL_DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
fi
msg_info "Setting up MySQL Database"
$STD mysql -u root -e "CREATE DATABASE \`${MYSQL_DB_NAME//\`/\`\`}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
$STD mysql -u root -e "CREATE USER '${MYSQL_DB_USER//\'/\'\'}'@'%' IDENTIFIED BY '${MYSQL_DB_PASS//\'/\'\'}';"
$STD mysql -u root -e "GRANT ALL ON \`${MYSQL_DB_NAME//\`/\`\`}\`.* TO '${MYSQL_DB_USER//\'/\'\'}'@'%';"
$STD mysql -u root -e "FLUSH PRIVILEGES;"
local app_name="${APPLICATION,,}"
local CREDS_FILE="${MYSQL_DB_CREDS_FILE:-${HOME}/${app_name}.creds}"
{
echo "MySQL Credentials"
echo "Database: $MYSQL_DB_NAME"
echo "User: $MYSQL_DB_USER"
echo "Password: $MYSQL_DB_PASS"
} >>"$CREDS_FILE"
msg_ok "Set up MySQL Database"
export MYSQL_DB_NAME
export MYSQL_DB_USER
export MYSQL_DB_PASS
}
# ------------------------------------------------------------------------------
# Installs or updates MeiliSearch search engine.
#
@@ -8252,17 +8195,22 @@ EOF
# ------------------------------------------------------------------------------
get_php_fpm_socket() {
local sock
if [[ -n "${PHP_VERSION:-}" && -S "/run/php/php${PHP_VERSION}-fpm.sock" ]]; then
echo "/run/php/php${PHP_VERSION}-fpm.sock"
return 0
fi
sock=$(find /run/php -maxdepth 1 -name "php*-fpm.sock" -type s 2>/dev/null | sort -V | tail -1)
if [[ -z "$sock" ]]; then
msg_error "No active PHP-FPM socket found under /run/php"
return 1
fi
echo "$sock"
}
# ------------------------------------------------------------------------------
# Enables an nginx site, validates the configuration and reloads the service.
#
@@ -8284,20 +8232,25 @@ get_php_fpm_socket() {
# ------------------------------------------------------------------------------
nginx_enable_site() {
local site="${1:-}"
if [[ -z "$site" ]]; then
msg_error "nginx_enable_site: no site name given"
return 1
fi
if [[ ! -f "/etc/nginx/sites-available/${site}" ]]; then
msg_error "nginx site config not found: /etc/nginx/sites-available/${site}"
return 1
fi
rm -f /etc/nginx/sites-enabled/default /etc/nginx/sites-available/default
ln -sf "/etc/nginx/sites-available/${site}" "/etc/nginx/sites-enabled/${site}"
if ! $STD nginx -t; then
msg_error "nginx configuration test failed for site '${site}'"
return 1
fi
$STD systemctl enable -q nginx
safe_service_restart nginx
}
@@ -9494,12 +9447,11 @@ get_latest_gitlab_release() {
local temp_file
temp_file=$(mktemp)
local gitlab_url="${GITLAB_URL:-https://gitlab.com}"
local http_code
http_code=$(curl --connect-timeout 10 --max-time 30 -sSL \
-w "%{http_code}" -o "$temp_file" \
"${header[@]}" \
"${gitlab_url}/api/v4/projects/$repo_encoded/releases?per_page=1&order_by=released_at&sort=desc" 2>/dev/null) || true
"https://gitlab.com/api/v4/projects/$repo_encoded/releases?per_page=1&order_by=released_at&sort=desc" 2>/dev/null) || true
if [[ "$http_code" != "200" ]]; then
rm -f "$temp_file"
@@ -9541,7 +9493,6 @@ get_latest_gitlab_release() {
# Notes:
# - Requires `jq` (auto-installed if missing)
# - Supports GITLAB_TOKEN env var for private/rate-limited repos
# - Supports GITLAB_URL for self-hosted GitLab (default: https://gitlab.com)
# - Does not modify anything, only checks version state
# ------------------------------------------------------------------------------
check_for_gl_release() {
@@ -9553,15 +9504,11 @@ check_for_gl_release() {
local app_lc="${app,,}"
local current_file="$HOME/.${app_lc}"
local gitlab_url="${GITLAB_URL:-https://gitlab.com}"
local gitlab_hostname="${gitlab_url#*://}"
gitlab_hostname="${gitlab_hostname%%/*}"
msg_info "Checking for update: ${app}"
# DNS check
if ! getent hosts "$gitlab_hostname" >/dev/null 2>&1; then
msg_error "Network error: cannot resolve $gitlab_hostname"
if ! getent hosts gitlab.com >/dev/null 2>&1; then
msg_error "Network error: cannot resolve gitlab.com"
return 6
fi
@@ -9584,7 +9531,7 @@ check_for_gl_release() {
local pinned_encoded="${pinned_version_in//\//%2F}"
http_code=$(curl -sSL --max-time 20 -w "%{http_code}" -o "$gl_check_json" \
"${header[@]}" \
"${gitlab_url}/api/v4/projects/$repo_encoded/releases/$pinned_encoded" 2>/dev/null) || true
"https://gitlab.com/api/v4/projects/$repo_encoded/releases/$pinned_encoded" 2>/dev/null) || true
if [[ "$http_code" == "200" ]] && [[ -s "$gl_check_json" ]]; then
releases_json="[$(<"$gl_check_json")]"
fi
@@ -9595,7 +9542,7 @@ check_for_gl_release() {
if [[ -z "$releases_json" ]]; then
http_code=$(curl -sSL --max-time 20 -w "%{http_code}" -o "$gl_check_json" \
"${header[@]}" \
"${gitlab_url}/api/v4/projects/$repo_encoded/releases?per_page=100&order_by=released_at&sort=desc" 2>/dev/null) || true
"https://gitlab.com/api/v4/projects/$repo_encoded/releases?per_page=100&order_by=released_at&sort=desc" 2>/dev/null) || true
if [[ "$http_code" == "200" ]] && [[ -s "$gl_check_json" ]]; then
releases_json=$(<"$gl_check_json")
@@ -9619,7 +9566,7 @@ check_for_gl_release() {
return 22
elif [[ "$http_code" == "000" || -z "$http_code" ]]; then
msg_error "GitLab API connection failed (no response)."
msg_error "Check your network/DNS: curl -sSL ${gitlab_url}/api/v4/version"
msg_error "Check your network/DNS: curl -sSL https://gitlab.com/api/v4/version"
rm -f "$gl_check_json"
return 7
else
@@ -9864,8 +9811,7 @@ fetch_and_deploy_gl_release() {
local repo_encoded
repo_encoded=$(printf '%s' "$repo" | sed 's|/|%2F|g')
local gitlab_url="${GITLAB_URL:-https://gitlab.com}"
local api_base="${gitlab_url}/api/v4/projects/$repo_encoded/releases"
local api_base="https://gitlab.com/api/v4/projects/$repo_encoded/releases"
local api_url
if [[ "$version" != "latest" ]]; then
api_url="$api_base/$version"
@@ -9914,7 +9860,7 @@ fetch_and_deploy_gl_release() {
msg_error " export GITLAB_TOKEN=\"glpat-your_token_here\""
elif [[ "$http_code" == "000" || -z "$http_code" ]]; then
msg_error "GitLab API connection failed (no response)."
msg_error "Check your network/DNS: curl -sSL ${gitlab_url}/api/v4/version"
msg_error "Check your network/DNS: curl -sSL https://gitlab.com/api/v4/version"
else
msg_error "Failed to fetch release metadata (HTTP $http_code)"
fi
@@ -9969,7 +9915,7 @@ fetch_and_deploy_gl_release() {
### Tarball Mode ###
if [[ "$mode" == "tarball" || "$mode" == "source" ]]; then
local direct_tarball_url="${gitlab_url}/$repo/-/archive/$tag_name/${app_lc}-${version_safe}.tar.gz"
local direct_tarball_url="https://gitlab.com/$repo/-/archive/$tag_name/${app_lc}-${version_safe}.tar.gz"
filename="${app_lc}-${version_safe}.tar.gz"
_download_source_tarball "$direct_tarball_url" "$tmpdir/$filename" "${header[@]}" || {
@@ -10017,7 +9963,7 @@ fetch_and_deploy_gl_release() {
if [[ -z "$url_match" ]]; then
local fallback_json
if fallback_json=$(_gl_scan_older_releases "$repo" "$repo_encoded" "$gitlab_url" "binary" "$asset_pattern" "$tag_name"); then
if fallback_json=$(_gl_scan_older_releases "$repo" "$repo_encoded" "https://gitlab.com" "binary" "$asset_pattern" "$tag_name"); then
json="$fallback_json"
tag_name=$(echo "$json" | jq -r '.tag_name // empty')
[[ "$tag_name" =~ ^v[0-9] ]] && version="${tag_name:1}" || version="$tag_name"
@@ -10089,7 +10035,7 @@ fetch_and_deploy_gl_release() {
if [[ -z "$asset_url" ]]; then
local fallback_json
if fallback_json=$(_gl_scan_older_releases "$repo" "$repo_encoded" "$gitlab_url" "prebuild" "$pattern" "$tag_name"); then
if fallback_json=$(_gl_scan_older_releases "$repo" "$repo_encoded" "https://gitlab.com" "prebuild" "$pattern" "$tag_name"); then
json="$fallback_json"
tag_name=$(echo "$json" | jq -r '.tag_name // empty')
[[ "$tag_name" =~ ^v[0-9] ]] && version="${tag_name:1}" || version="$tag_name"
@@ -10142,7 +10088,7 @@ fetch_and_deploy_gl_release() {
if [[ -z "$asset_url" ]]; then
local fallback_json
if fallback_json=$(_gl_scan_older_releases "$repo" "$repo_encoded" "$gitlab_url" "singlefile" "$pattern" "$tag_name"); then
if fallback_json=$(_gl_scan_older_releases "$repo" "$repo_encoded" "https://gitlab.com" "singlefile" "$pattern" "$tag_name"); then
json="$fallback_json"
tag_name=$(echo "$json" | jq -r '.tag_name // empty')
[[ "$tag_name" =~ ^v[0-9] ]] && version="${tag_name:1}" || version="$tag_name"
+23 -29
View File
@@ -6,19 +6,6 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://netbird.io/ | Github: https://github.com/netbirdio/netbird
APP="add-netbird-lxc"
APP_TYPE="addon"
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-netbird-lxc" "addon"
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
function header_info {
clear
cat <<"EOF"
@@ -30,22 +17,28 @@ function header_info {
EOF
}
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
header_info
set -e
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-netbird-lxc" "addon"
while true; do
read -r -p "This will add NetBird to an existing LXC Container ONLY. Proceed(y/n)?" yn
read -p "This will add NetBird to an existing LXC Container ONLY. Proceed(y/n)?" yn
case $yn in
[Yy]*) break ;;
[Nn]*) exit 0 ;;
[Nn]*) exit ;;
*) echo "Please answer yes or no." ;;
esac
done
header_info
msg_info "Loading container list..."
echo "Loading..."
function msg() {
local TEXT="$1"
echo -e "$TEXT"
}
NODE=$(hostname)
MSG_MAX_LENGTH=0
@@ -68,28 +61,28 @@ done
LXC_STATUS=$(pct status "$CTID" | awk '{print $2}')
if [[ "$LXC_STATUS" != "running" ]]; then
msg_info "Container $CTID is not running. Starting it now..."
msg "\e[1;33m The container $CTID is not running. Starting it now...\e[0m"
pct start "$CTID"
while [[ "$(pct status "$CTID" | awk '{print $2}')" != "running" ]]; do
msg_info "Waiting for the container to start..."
msg "\e[1;33m Waiting for the container to start...\e[0m"
sleep 2
done
msg_ok "Container $CTID is now running."
msg "\e[1;32m Container $CTID is now running.\e[0m"
fi
DISTRO=$(pct exec "$CTID" -- cat /etc/os-release | grep -w "ID" | cut -d'=' -f2 | tr -d '"')
if [[ "$DISTRO" != "debian" && "$DISTRO" != "ubuntu" ]]; then
msg_error "This script only supports Debian or Ubuntu LXC containers. Detected: $DISTRO. Aborting..."
msg "\e[1;31m Error: This script only supports Debian or Ubuntu LXC containers. Detected: $DISTRO. Aborting...\e[0m"
exit 238
fi
CTID_CONFIG_PATH="/etc/pve/lxc/${CTID}.conf"
cat <<EOF >>"$CTID_CONFIG_PATH"
CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf
cat <<EOF >>$CTID_CONFIG_PATH
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
EOF
header_info
msg_info "Installing NetBird"
msg "Installing NetBird..."
pct exec "$CTID" -- bash -c '
if ! command -v curl &>/dev/null; then
apt-get update -qq
@@ -110,5 +103,6 @@ OVERRIDE
systemctl daemon-reload
fi
'
msg_ok "Installed NetBird."
echo -e "${YW}Reboot ${CTID} LXC${CL} to apply the changes, then run 'netbird up' in the LXC console"
msg "\e[1;32m ✔ Installed NetBird.\e[0m"
sleep 2
msg "\e[1;31m Reboot ${CTID} LXC to apply the changes, then run netbird up in the LXC console\e[0m"
+9 -14
View File
@@ -5,18 +5,8 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://tailscale.com/ | Github: https://github.com/tailscale/tailscale
APP="add-tailscale-lxc"
APP_TYPE="addon"
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-tailscale-lxc" "addon"
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
trap 'echo -e "\n[ERROR] in line $LINENO: exit code $?"' ERR
function header_info() {
clear
@@ -30,8 +20,13 @@ function header_info() {
EOF
}
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
function msg_info() { echo -e " \e[1;36m➤\e[0m $1"; }
function msg_ok() { echo -e " \e[1;32m✔\e[0m $1"; }
function msg_error() { echo -e " \e[1;31m✖\e[0m $1"; }
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-tailscale-lxc" "addon"
header_info
@@ -173,4 +168,4 @@ TAGS="${TAGS:+$TAGS; }tailscale"
pct set "$CTID" -tags "$TAGS"
msg_ok "Tailscale installed on CT $CTID"
echo -e "${YW}Reboot the container${CL}, then run 'tailscale up' inside the container to activate."
msg_info "Reboot the container, then run 'tailscale up' inside the container to activate."
+38 -10
View File
@@ -10,8 +10,8 @@ if ! command -v curl &>/dev/null; then
if [[ -f "/etc/alpine-release" ]]; then
apk -U add curl >/dev/null 2>&1
else
apt update >/dev/null 2>&1
apt install -y curl >/dev/null 2>&1
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
@@ -36,6 +36,28 @@ DEFAULT_PORT=8080
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
# ==============================================================================
# HEADER
# ==============================================================================
function header_info {
clear
cat <<"EOF"
___ __ ____ __ _____
/ | ____/ /___ ___ ______ __________/ / / / /___ ____ ___ ___ / ___/__ ______ _____
/ /| |/ __ / __ `/ / / / __ `/ ___/ __ / /_/ / __ \/ __ `__ \/ _ \ \__ \/ / / / __ \/ ___/
/ ___ / /_/ / /_/ / /_/ / /_/ / / / /_/ / __ / /_/ / / / / / / __/ ___/ / /_/ / / / / /__
/_/ |_\__,_/\__, /\__,_/\__,_/_/ \__,_/_/ /_/\____/_/ /_/ /_/\___/ /____/\__, /_/ /_/\___/
/____/ /____/
EOF
}
# ==============================================================================
# HELPER FUNCTIONS
# ==============================================================================
get_ip() {
hostname -I 2>/dev/null | awk '{print $1}' || ip -4 addr show scope global 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1 || echo "127.0.0.1"
}
# ==============================================================================
# OS DETECTION
# ==============================================================================
@@ -92,12 +114,16 @@ function update() {
fi
msg_ok "Stopped service"
BACKUP_DIR="/opt/adguardhome-sync_backup"
create_backup "$CONFIG_PATH"
msg_info "Backing up configuration"
cp "$CONFIG_PATH" /tmp/adguardhome-sync.yaml.bak 2>/dev/null || true
msg_ok "Backed up configuration"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "adguardhome-sync" "bakito/adguardhome-sync" "prebuild" "latest" "$INSTALL_PATH" "adguardhome-sync_*_linux_$(arch_resolve).tar.gz"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "adguardhome-sync" "bakito/adguardhome-sync" "prebuild" "latest" "$INSTALL_PATH" "adguardhome-sync_*_linux_amd64.tar.gz"
restore_backup
msg_info "Restoring configuration"
cp /tmp/adguardhome-sync.yaml.bak "$CONFIG_PATH" 2>/dev/null || true
rm -f /tmp/adguardhome-sync.yaml.bak
msg_ok "Restored configuration"
msg_info "Starting service"
if [[ "$OS" == "Alpine" ]]; then
@@ -115,7 +141,10 @@ function update() {
# INSTALL
# ==============================================================================
function install() {
fetch_and_deploy_gh_release "adguardhome-sync" "bakito/adguardhome-sync" "prebuild" "latest" "$INSTALL_PATH" "adguardhome-sync_*_linux_$(arch_resolve).tar.gz"
local ip
ip=$(get_ip)
fetch_and_deploy_gh_release "adguardhome-sync" "bakito/adguardhome-sync" "prebuild" "latest" "$INSTALL_PATH" "adguardhome-sync_*_linux_amd64.tar.gz"
# Gather configuration from user
echo ""
@@ -264,7 +293,7 @@ UPDATEEOF
echo ""
msg_ok "${APP} installed successfully"
msg_ok "Web UI: ${BL}http://${IP}:${DEFAULT_PORT}${CL}"
msg_ok "Web UI: ${BL}http://${ip}:${DEFAULT_PORT}${CL}"
msg_ok "Config: ${BL}${CONFIG_PATH}${CL}"
echo ""
msg_warn "Edit the config file to add your AdGuardHome instances!"
@@ -290,8 +319,7 @@ fi
header_info
get_lxc_ip
IP="$LOCAL_IP"
IP=$(get_ip)
# Check if already installed
if [[ -d "$INSTALL_PATH" && -f "$INSTALL_PATH/adguardhome-sync" ]]; then
+57 -61
View File
@@ -1,17 +1,8 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
APP="all-templates"
APP_TYPE="addon"
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "all-templates" "addon"
# License: MIT
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
function header_info {
clear
@@ -24,17 +15,37 @@ function header_info {
EOF
}
# Enable error handling; destroy any partially-created container before reporting the error
set -Eeuo pipefail
function _cleanup_on_error() {
local ec=$? cmd="$BASH_COMMAND"
[[ -n "${CTID:-}" ]] && cleanup_ctid
error_handler "$ec" "$cmd"
set -eEuo pipefail
shopt -s expand_aliases
alias die='EXIT=$? LINE=$LINENO error_exit'
trap die ERR
function error_exit() {
trap - ERR
local DEFAULT='Unknown failure occured.'
local REASON="\e[97m${1:-$DEFAULT}\e[39m"
local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE"
msg "$FLAG $REASON" 1>&2
[ ! -z ${CTID-} ] && cleanup_ctid
exit $EXIT
}
function warn() {
local REASON="\e[97m$1\e[39m"
local FLAG="\e[93m[WARNING]\e[39m"
msg "$FLAG $REASON"
}
function info() {
local REASON="$1"
local FLAG="\e[36m[INFO]\e[39m"
msg "$FLAG $REASON"
}
function msg() {
local TEXT="$1"
echo -e "$TEXT"
}
trap '_cleanup_on_error' ERR
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "all-templates" "addon"
function validate_container_id() {
local ctid="$1"
@@ -73,7 +84,7 @@ if systemctl is-active -q ping-instances.service; then
systemctl stop ping-instances.service
fi
header_info
msg_info "Loading"
echo "Loading..."
pveam update >/dev/null 2>&1
whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Templates" --yesno "This will allow for the creation of one of the many Template LXC Containers. Proceed?" 10 68
TEMPLATE_MENU=()
@@ -86,8 +97,8 @@ done < <(pveam available)
TEMPLATE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Template LXCs" --radiolist "\nSelect a Template LXC to create:\n" 16 $((MSG_MAX_LENGTH + 58)) 10 "${TEMPLATE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"')
[ -z "$TEMPLATE" ] && {
whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Template LXC Selected" --msgbox "It appears that no Template LXC container was selected" 10 68
echo "Done"
exit 0
msg "Done"
exit
}
# Setup script environment
@@ -97,9 +108,9 @@ PASS="$(openssl rand -base64 8)"
# Get valid Container ID
CTID=$(pvesh get /cluster/nextid)
if ! validate_container_id "$CTID"; then
msg_warn "Container ID $CTID is already in use."
warn "Container ID $CTID is already in use."
CTID=$(get_valid_container_id "$CTID")
msg_info "Using next available ID: $CTID"
info "Using next available ID: $CTID"
fi
PCT_OPTIONS="
@@ -131,10 +142,7 @@ function select_storage() {
CONTENT='vztmpl'
CONTENT_LABEL='Container template'
;;
*)
msg_error "Invalid storage class."
exit 1
;;
*) false || die "Invalid storage class." ;;
esac
# Query all storage locations
@@ -153,9 +161,8 @@ function select_storage() {
# Select storage location
if [ $((${#MENU[@]} / 3)) -eq 0 ]; then
msg_warn "'$CONTENT_LABEL' needs to be selected for at least one storage location."
msg_error "Unable to detect valid storage location."
exit 1
warn "'$CONTENT_LABEL' needs to be selected for at least one storage location."
die "Unable to detect valid storage location."
elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then
printf ${MENU[0]}
else
@@ -164,10 +171,7 @@ function select_storage() {
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
"Which storage pool would you like to use for the ${CONTENT_LABEL,,}?\n\n" \
16 $(($MSG_MAX_LENGTH + 23)) 6 \
"${MENU[@]}" 3>&1 1>&2 2>&3) || {
msg_error "Menu aborted."
exit 1
}
"${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted."
done
printf $STORAGE
fi
@@ -175,43 +179,35 @@ function select_storage() {
header_info
# Get template storage
TEMPLATE_STORAGE=$(select_storage template)
msg_info "Using '$TEMPLATE_STORAGE' for template storage."
info "Using '$TEMPLATE_STORAGE' for template storage."
# Get container storage
CONTAINER_STORAGE=$(select_storage container)
msg_info "Using '$CONTAINER_STORAGE' for container storage."
info "Using '$CONTAINER_STORAGE' for container storage."
# Download template
msg_info "Downloading LXC template (Patience)"
pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || {
msg_error "A problem occured while downloading the LXC template."
exit 1
}
msg_ok "Downloaded LXC template"
msg "Downloading LXC template (Patience)..."
pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template."
# Create variable for 'pct' options
PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
[[ " ${PCT_OPTIONS[*]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8})
[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8})
# Create LXC
msg_info "Creating LXC container"
pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} "${PCT_OPTIONS[@]}" >/dev/null || {
msg_error "A problem occured while trying to create container."
exit 1
}
msg_ok "Created LXC container"
msg "Creating LXC container..."
pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null ||
die "A problem occured while trying to create container."
# Save password
echo "$NAME password: ${PASS}" >>~/$NAME.creds # file is located in the Proxmox root directory
# Start container
msg_info "Starting LXC Container"
msg "Starting LXC Container..."
pct start "$CTID"
sleep 5
msg_ok "Started LXC Container"
# Get container IP
set +Eeuo pipefail
set +eEuo pipefail
max_attempts=5
attempt=1
IP=""
@@ -220,18 +216,18 @@ while [[ $attempt -le $max_attempts ]]; do
if [[ -n $IP ]]; then
break
else
msg_warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..."
warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..."
sleep 5
((attempt++))
fi
done
if [[ -z $IP ]]; then
msg_warn "Maximum number of attempts reached. IP address not found."
warn "Maximum number of attempts reached. IP address not found."
IP="NOT FOUND"
fi
set -Eeuo pipefail
set -eEuo pipefail
# Start Proxmox VE Monitor-All if available
if [[ -f /etc/systemd/system/ping-instances.service ]]; then
systemctl start ping-instances.service
@@ -240,10 +236,10 @@ fi
# Success message
header_info
echo
msg_ok "LXC container '$CTID' was successfully created, and its IP address is ${IP}."
info "LXC container '$CTID' was successfully created, and its IP address is ${IP}."
echo
echo -e "${YW}Proceed to the LXC console to complete the setup.${CL}"
info "Proceed to the LXC console to complete the setup."
echo
echo -e "${YW}login: root${CL}"
echo -e "${YW}password: $PASS${CL}"
info "login: root"
info "password: $PASS"
echo
+17 -2
View File
@@ -6,8 +6,8 @@
# Source: https://github.com/getarcaneapp/arcane
if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt update >/dev/null 2>&1
apt install -y curl >/dev/null 2>&1
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -32,6 +32,21 @@ DEFAULT_PORT=3552
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
# ==============================================================================
# HEADER
# ==============================================================================
function header_info {
clear
cat <<"EOF"
___ ____ _________ _ ________
/ | / __ \/ ____/ | / | / / ____/
/ /| | / /_/ / / / /| | / |/ / __/
/ ___ |/ _, _/ /___/ ___ |/ /| / /___
/_/ |_/_/ |_|\____/_/ |_/_/ |_/_____/
EOF
}
# ==============================================================================
# UNINSTALL
# ==============================================================================
+96 -134
View File
@@ -5,149 +5,62 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://coder.com/ | Github: https://github.com/coder/code-server
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
function header_info {
cat <<"EOF"
______ __ _____
/ ____/___ ____/ /__ / ___/___ ______ _____ _____
/ / / __ \/ __ / _ \ \__ \/ _ \/ ___/ | / / _ \/ ___/
/ /___/ /_/ / /_/ / __/ ___/ / __/ / | |/ / __/ /
\____/\____/\__,_/\___/ /____/\___/_/ |___/\___/_/
EOF
}
IP=$(hostname -I | awk '{print $1}')
YW=$(echo "\033[33m")
BL=$(echo "\033[36m")
RD=$(echo "\033[01;31m")
BGN=$(echo "\033[4;92m")
GN=$(echo "\033[1;92m")
DGN=$(echo "\033[32m")
CL=$(echo "\033[m")
BFR="\\r\\033[K"
HOLD="-"
CM="${GN}${CL}"
APP="Coder Code Server"
hostname="$(hostname)"
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "coder-code-server" "addon"
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
APP="Coder Code Server"
APP_TYPE="addon"
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
set -o errexit
set -o errtrace
set -o nounset
set -o pipefail
shopt -s expand_aliases
alias die='EXIT=$? LINE=$LINENO error_exit'
trap die ERR
function error_exit() {
trap - ERR
local reason="Unknown failure occured."
local msg="${1:-$reason}"
local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE"
echo -e "$flag $msg" 1>&2
exit "$EXIT"
}
clear
header_info
ensure_usr_local_bin_persist
get_lxc_ip
IP="$LOCAL_IP"
if command -v pveversion >/dev/null 2>&1; then
msg_error "Can't Install on Proxmox"
exit 1
echo -e "⚠️ Can't Install on Proxmox "
exit
fi
if [ -e /etc/alpine-release ]; then
msg_error "Can't Install on Alpine"
exit 1
echo -e "⚠️ Can't Install on Alpine"
exit
fi
# ==============================================================================
# UNINSTALL
# ==============================================================================
function uninstall() {
msg_info "Uninstalling ${APP}"
systemctl disable --now code-server@"$USER" &>/dev/null || true
$STD apt remove -y code-server
rm -f "$HOME/.coder-code-server"
msg_ok "${APP} has been uninstalled"
}
# ==============================================================================
# UPDATE
# ==============================================================================
function update() {
if check_for_gh_release "coder-code-server" "coder/code-server"; then
msg_info "Updating ${APP}"
fetch_and_deploy_gh_release "coder-code-server" "coder/code-server" "binary" "latest" "/opt/coder-code-server" "code-server_*_$(arch_resolve).deb"
systemctl restart code-server@"$USER"
msg_ok "Updated successfully!"
exit
fi
}
# ==============================================================================
# INSTALL
# ==============================================================================
function install() {
msg_info "Installing Dependencies"
$STD apt update
$STD apt install -y \
curl \
git
msg_ok "Installed Dependencies"
msg_info "Installing ${APP}"
config_path="${HOME}/.config/code-server/config.yaml"
preexisting_config=false
if [ -f "$config_path" ]; then
preexisting_config=true
fi
fetch_and_deploy_gh_release "coder-code-server" "coder/code-server" "binary" "latest" "/opt/coder-code-server" "code-server_*_$(arch_resolve).deb"
mkdir -p "${HOME}/.config/code-server/"
if [ "$preexisting_config" = false ]; then
cat <<EOF >"$config_path"
bind-addr: 0.0.0.0:8680
auth: none
password:
cert: false
EOF
fi
systemctl enable -q --now code-server@"$USER"
systemctl restart code-server@"$USER"
if ! systemctl is-active --quiet code-server@"$USER"; then
msg_error "code-server service failed to start."
exit 1
fi
msg_ok "Installed ${APP}"
msg_info "Creating update script"
ensure_usr_local_bin_persist
cat <<'EOF' >/usr/local/bin/update_coder-code-server
#!/usr/bin/env bash
# Coder Code Server Update Script
type=update bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/coder-code-server.sh)"
EOF
chmod +x /usr/local/bin/update_coder-code-server
msg_ok "Created update script (/usr/local/bin/update_coder-code-server)"
echo -e "${APP} should be reachable by going to the following URL.
${BL}http://${IP}:8680${CL} \n"
}
# ==============================================================================
# MAIN
# ==============================================================================
# Handle type=update (called from update script)
if [[ "${type:-}" == "update" ]]; then
if command -v code-server &>/dev/null; then
update
else
msg_error "${APP} is not installed. Nothing to update."
exit 233
fi
exit 0
fi
if [[ -d "$HOME" && -f "$HOME/.coder-code-server" ]] || command -v code-server &>/dev/null; then
msg_warn "${APP} is already installed."
echo -n "${TAB}Uninstall ${APP}? (y/N): "
read -r uninstall_prompt
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
uninstall
exit 0
fi
echo -n "${TAB}Update ${APP}? (y/N): "
read -r update_prompt
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
update
exit 0
fi
msg_warn "No action selected. Exiting."
exit 0
fi
while true; do
echo -n "${TAB}This will Install ${APP}. Proceed (y/n)? "
read -r yn
read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn
case $yn in
[Yy]*) break ;;
[Nn]*) exit ;;
@@ -155,4 +68,53 @@ while true; do
esac
done
install
function msg_info() {
local msg="$1"
echo -ne " ${HOLD} ${YW}${msg}..."
}
function msg_ok() {
local msg="$1"
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
}
msg_info "Installing Dependencies"
apt-get update &>/dev/null
apt-get install -y curl &>/dev/null
apt-get install -y git &>/dev/null
msg_ok "Installed Dependencies"
VERSION=$(curl -fsSL https://api.github.com/repos/coder/code-server/releases/latest |
grep "tag_name" |
awk '{print substr($2, 3, length($2)-4) }')
msg_info "Installing Code-Server v${VERSION}"
config_path="${HOME}/.config/code-server/config.yaml"
preexisting_config=false
if [ -f "$config_path" ]; then
preexisting_config=true
fi
curl -fOL https://github.com/coder/code-server/releases/download/v"$VERSION"/code-server_"${VERSION}"_amd64.deb &>/dev/null
dpkg -i code-server_"${VERSION}"_amd64.deb &>/dev/null
rm -rf code-server_"${VERSION}"_amd64.deb
mkdir -p "${HOME}/.config/code-server/"
if [ "$preexisting_config" = false ]; then
cat <<EOF >"$config_path"
bind-addr: 0.0.0.0:8680
auth: none
password:
cert: false
EOF
fi
systemctl enable -q --now code-server@"$USER"
systemctl restart code-server@"$USER"
if ! systemctl is-active --quiet code-server@"$USER"; then
error_exit "code-server service failed to start."
fi
msg_ok "Installed Code-Server v${VERSION} on $hostname"
echo -e "${APP} should be reachable by going to the following URL.
${BL}http://$IP:8680${CL} \n"
+20 -13
View File
@@ -7,8 +7,8 @@
if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt update >/dev/null 2>&1
apt install -y curl >/dev/null 2>&1
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -45,13 +45,28 @@ if [[ -f "/etc/alpine-release" ]]; then
SERVICE_PATH="/etc/init.d/copyparty"
elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
OS="Debian"
PKG_MANAGER="apt install -y"
PKG_MANAGER="apt-get install -y"
SERVICE_PATH="/etc/systemd/system/copyparty.service"
else
msg_error "Unsupported OS detected. Exiting."
exit 238
fi
# ==============================================================================
# HEADER
# ==============================================================================
function header_info() {
clear
cat <<"EOF"
______ ____ __
/ ____/___ ____ __ __/ __ \____ ______/ /___ __
/ / / __ \/ __ \/ / / / /_/ / __ `/ ___/ __/ / / /
/ /___/ /_/ / /_/ / /_/ / ____/ /_/ / / / /_/ /_/ /
\____/\____/ .___/\__, /_/ \__,_/_/ \__/\__, /
/_/ /____/ /____/
EOF
}
# ==============================================================================
# HELPER FUNCTIONS
# ==============================================================================
@@ -158,17 +173,9 @@ function install() {
msg_info "Installing dependencies"
if [[ "$OS" == "Debian" ]]; then
$STD $PKG_MANAGER \
python3 \
python3-pil \
ffmpeg \
curl
$STD $PKG_MANAGER python3 python3-pil ffmpeg curl
else
$STD $PKG_MANAGER \
python3 \
py3-pillow \
ffmpeg \
curl
$STD $PKG_MANAGER python3 py3-pillow ffmpeg curl
fi
msg_ok "Dependencies installed (with thumbnail support)"
+24 -5
View File
@@ -7,8 +7,8 @@
if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt update >/dev/null 2>&1
apt install -y curl >/dev/null 2>&1
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -31,6 +31,21 @@ CONFIG_PATH="/opt/cronmaster/.env"
SERVICE_PATH="/etc/systemd/system/cronmaster.service"
DEFAULT_PORT=3000
# ==============================================================================
# HEADER
# ==============================================================================
function header_info {
clear
cat <<"EOF"
______ __ ___ __
/ ____/________ ____ / |/ /___ ______/ /____ _____
/ / / ___/ __ \/ __ \/ /|_/ / __ `/ ___/ __/ _ \/ ___/
/ /___/ / / /_/ / / / / / / / /_/ (__ ) /_/ __/ /
\____/_/ \____/_/ /_/_/ /_/\__,_/____/\__/\___/_/
EOF
}
# ==============================================================================
# OS DETECTION
# ==============================================================================
@@ -62,12 +77,16 @@ function update() {
systemctl stop cronmaster.service &>/dev/null || true
msg_ok "Stopped service"
BACKUP_DIR="/opt/cronmaster_backup"
create_backup "$CONFIG_PATH"
msg_info "Backing up configuration"
cp "$CONFIG_PATH" /tmp/cronmaster.env.bak 2>/dev/null || true
msg_ok "Backed up configuration"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cronmaster" "fccview/cronmaster" "prebuild" "latest" "$INSTALL_PATH" "cronmaster_*_prebuild.tar.gz"
restore_backup
msg_info "Restoring configuration"
cp /tmp/cronmaster.env.bak "$CONFIG_PATH" 2>/dev/null || true
rm -f /tmp/cronmaster.env.bak
msg_ok "Restored configuration"
msg_info "Starting service"
systemctl start cronmaster
+61 -26
View File
@@ -5,54 +5,89 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.crowdsec.net/ | Github: https://github.com/crowdsecurity/crowdsec
YW=$(echo "\033[33m")
BL=$(echo "\033[36m")
RD=$(echo "\033[01;31m")
BGN=$(echo "\033[4;92m")
GN=$(echo "\033[1;92m")
DGN=$(echo "\033[32m")
CL=$(echo "\033[m")
BFR="\\r\\033[K"
HOLD="-"
CM="${GN}${CL}"
APP="CrowdSec"
APP_TYPE="addon"
hostname="$(hostname)"
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "crowdsec" "addon"
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
header_info
set -o errexit
set -o errtrace
set -o nounset
set -o pipefail
shopt -s expand_aliases
alias die='EXIT=$? LINE=$LINENO error_exit'
trap die ERR
function error_exit() {
trap - ERR
local reason="Unknown failure occured."
local msg="${1:-$reason}"
local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE"
echo -e "$flag $msg" 1>&2
exit "$EXIT"
}
if command -v pveversion >/dev/null 2>&1; then
msg_error "Can't Install on Proxmox"
exit 1
echo -e "⚠️ Can't Install on Proxmox "
exit
fi
while true; do
echo -n "${TAB}This will Install ${APP}. Proceed (y/n)? "
read -r yn
read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn
case $yn in
[Yy]*) break ;;
[Nn]*) exit ;;
*) echo "Please answer yes or no." ;;
esac
done
clear
function header_info() {
echo -e "${BL}
_____ _ _____
/ ____| | |/ ____|
| | _ __ _____ ____| | (___ ___ ___
| | | __/ _ \ \ /\ / / _ |\___ \ / _ \/ __|
| |____| | | (_) \ V V / (_| |____) | __/ (__
\_____|_| \___/ \_/\_/ \__ _|_____/ \___|\___|
${CL}"
}
header_info
function msg_info() {
local msg="$1"
echo -ne " ${HOLD} ${YW}${msg}..."
}
function msg_ok() {
local msg="$1"
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
}
msg_info "Setting up ${APP} Repository"
$STD apt update
$STD apt install -y \
curl \
gnupg
$STD bash -c "curl -fsSL https://install.crowdsec.net | bash"
apt-get update &>/dev/null
apt-get install -y curl &>/dev/null
apt-get install -y gnupg &>/dev/null
curl -fsSL "https://install.crowdsec.net" | bash &>/dev/null
msg_ok "Setup ${APP} Repository"
msg_info "Installing ${APP}"
$STD apt update
$STD apt install -y crowdsec
msg_ok "Installed ${APP}"
apt-get update &>/dev/null
apt-get install -y crowdsec &>/dev/null
msg_ok "Installed ${APP} on $hostname"
msg_info "Installing ${APP} Common Bouncer"
$STD apt install -y crowdsec-firewall-bouncer-iptables
apt-get install -y crowdsec-firewall-bouncer-iptables &>/dev/null
msg_ok "Installed ${APP} Common Bouncer"
msg_ok "Completed successfully!\n"
+74 -56
View File
@@ -5,41 +5,55 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/filebrowserspace/quantum
function header_info() {
clear
cat <<"EOF"
_______ __ ____ ____ __
/ ____(_) /__ / __ )_________ _ __________ _____ / __ \__ ______ _____ / /___ ______ ___
/ /_ / / / _ \/ __ / ___/ __ \ | /| / / ___/ _ \/ ___/ / / / / / / / __ `/ __ \/ __/ / / / __ `__ \
/ __/ / / / __/ /_/ / / / /_/ / |/ |/ (__ ) __/ / / /_/ / /_/ / /_/ / / / / /_/ /_/ / / / / / /
/_/ /_/_/\___/_____/_/ \____/|__/|__/____/\___/_/ \___\_\__,_/\__,_/_/ /_/\__/\__,_/_/ /_/ /_/
EOF
}
YW=$(echo "\033[33m")
GN=$(echo "\033[1;92m")
RD=$(echo "\033[01;31m")
BL=$(echo "\033[36m")
CL=$(echo "\033[m")
CM="${GN}✔️${CL}"
CROSS="${RD}✖️${CL}"
INFO="${BL}${CL}"
APP="FileBrowser Quantum"
APP_TYPE="addon"
INSTALL_PATH="/usr/local/bin/filebrowser"
CONFIG_PATH="/usr/local/community-scripts/fq-config.yaml"
DEFAULT_PORT=8080
SRC_DIR="/"
TMP_BIN="/tmp/filebrowser.$$"
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "filebrowser-quantum" "addon"
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
header_info
get_lxc_ip
IP="$LOCAL_IP"
# Get primary IP
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
[[ -z "$IP" ]] && IP=$(hostname -I | awk '{print $1}')
[[ -z "$IP" ]] && IP="127.0.0.1"
# Proxmox Host Warning
if [[ -d "/etc/pve" ]]; then
msg_warn "Running this addon directly on the Proxmox host is not recommended!"
msg_warn "Only the boot disk will be visible — passthrough drives will not be indexed."
msg_warn "This causes incorrect disk usage stats and incomplete file browsing."
msg_warn "Run this addon inside an LXC or VM instead and mount your drives there."
echo -e "${RD}⚠️ Warning: Running this addon directly on the Proxmox host is not recommended!${CL}"
echo -e "${YW} Only the boot disk will be visible — passthrough drives will not be indexed.${CL}"
echo -e "${YW} This causes incorrect disk usage stats and incomplete file browsing.${CL}"
echo -e "${YW} Run this addon inside an LXC or VM instead and mount your drives there.${CL}"
echo ""
echo -n "${TAB}Continue anyway on the Proxmox host? (y/N): "
echo -n "Continue anyway on the Proxmox host? (y/N): "
read -r host_confirm
if [[ ! "${host_confirm,,}" =~ ^(y|yes)$ ]]; then
msg_error "Aborted."
echo -e "${YW}Aborted.${CL}"
exit 0
fi
fi
@@ -52,12 +66,18 @@ if [[ -f "/etc/alpine-release" ]]; then
elif [[ -f "/etc/debian_version" ]]; then
OS="Debian"
SERVICE_PATH="/etc/systemd/system/filebrowser.service"
PKG_MANAGER="apt install -y"
PKG_MANAGER="apt-get install -y"
else
msg_error "Unsupported OS detected. Exiting."
echo -e "${CROSS} Unsupported OS detected. Exiting."
exit 238
fi
header_info
function msg_info() { echo -e "${INFO} ${YW}$1...${CL}"; }
function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; }
function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
# Detect legacy FileBrowser installation
LEGACY_DB="/usr/local/community-scripts/filebrowser.db"
LEGACY_BIN="/usr/local/bin/filebrowser"
@@ -65,82 +85,80 @@ LEGACY_SERVICE_DEB="/etc/systemd/system/filebrowser.service"
LEGACY_SERVICE_ALP="/etc/init.d/filebrowser"
if [[ -f "$LEGACY_DB" || -f "$LEGACY_BIN" && ! -f "$CONFIG_PATH" ]]; then
msg_warn "Detected legacy FileBrowser installation."
echo -n "${TAB}Uninstall legacy FileBrowser and continue with Quantum install? (y/n): "
echo -e "${YW}⚠️ Detected legacy FileBrowser installation.${CL}"
echo -n "Uninstall legacy FileBrowser and continue with Quantum install? (y/n): "
read -r remove_legacy
if [[ "${remove_legacy,,}" =~ ^(y|yes)$ ]]; then
msg_info "Uninstalling legacy FileBrowser"
if [[ -f "$LEGACY_SERVICE_DEB" ]]; then
systemctl disable --now filebrowser.service &>/dev/null || true
systemctl disable --now filebrowser.service &>/dev/null
rm -f "$LEGACY_SERVICE_DEB"
elif [[ -f "$LEGACY_SERVICE_ALP" ]]; then
rc-service filebrowser stop &>/dev/null || true
rc-update del filebrowser &>/dev/null || true
rc-service filebrowser stop &>/dev/null
rc-update del filebrowser &>/dev/null
rm -f "$LEGACY_SERVICE_ALP"
fi
rm -f "$LEGACY_BIN" "$LEGACY_DB"
msg_ok "Legacy FileBrowser removed"
else
msg_error "Installation aborted by user."
echo -e "${YW}Installation aborted by user.${CL}"
exit 0
fi
fi
# Existing installation
if [[ -f "$INSTALL_PATH" ]]; then
msg_warn "${APP} is already installed."
echo -n "${TAB}Uninstall ${APP}? (y/N): "
echo -e "${YW}⚠️ ${APP} is already installed.${CL}"
echo -n "Uninstall ${APP}? (y/N): "
read -r uninstall_prompt
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Uninstalling ${APP}"
if [[ "$OS" == "Debian" ]]; then
systemctl disable --now filebrowser.service &>/dev/null || true
systemctl disable --now filebrowser.service &>/dev/null
rm -f "$SERVICE_PATH"
else
rc-service filebrowser stop &>/dev/null || true
rc-update del filebrowser &>/dev/null || true
rc-service filebrowser stop &>/dev/null
rc-update del filebrowser &>/dev/null
rm -f "$SERVICE_PATH"
fi
rm -f "$INSTALL_PATH" "$CONFIG_PATH" "$HOME/.filebrowser-quantum"
rm -f "$INSTALL_PATH" "$CONFIG_PATH"
msg_ok "${APP} has been uninstalled."
exit 0
fi
echo -n "${TAB}Update ${APP}? (y/N): "
echo -n "Update ${APP}? (y/N): "
read -r update_prompt
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
if check_for_gh_release "filebrowser-quantum" "gtsteffaniak/filebrowser"; then
msg_info "Updating ${APP}"
if ! command -v curl &>/dev/null; then $STD $PKG_MANAGER curl; fi
fetch_and_deploy_gh_release "filebrowser-quantum" "gtsteffaniak/filebrowser" "singlefile" "latest" "/usr/local/bin" "linux-$(arch_resolve)-filebrowser"
mv -f /usr/local/bin/filebrowser-quantum "$INSTALL_PATH"
msg_ok "Updated ${APP}"
fi
msg_info "Updating ${APP}"
if ! command -v curl &>/dev/null; then $PKG_MANAGER curl &>/dev/null; fi
curl -fsSL https://github.com/gtsteffaniak/filebrowser/releases/latest/download/linux-amd64-filebrowser -o "$TMP_BIN"
chmod +x "$TMP_BIN"
mv -f "$TMP_BIN" /usr/local/bin/filebrowser
msg_ok "Updated ${APP}"
exit 0
else
msg_warn "Update skipped. Exiting."
echo -e "${YW}⚠️ Update skipped. Exiting.${CL}"
exit 0
fi
fi
msg_warn "${APP} is not installed."
echo -n "${TAB}Enter port number (Default: ${DEFAULT_PORT}): "
echo -e "${YW}⚠️ ${APP} is not installed.${CL}"
echo -n "Enter port number (Default: ${DEFAULT_PORT}): "
read -r PORT
PORT=${PORT:-$DEFAULT_PORT}
echo -n "${TAB}Install ${APP}? (y/n): "
echo -n "Install ${APP}? (y/n): "
read -r install_prompt
if ! [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_warn "Installation skipped. Exiting."
echo -e "${YW}⚠️ Installation skipped. Exiting.${CL}"
exit 0
fi
msg_info "Installing ${APP} on ${OS}"
$STD $PKG_MANAGER \
curl \
ffmpeg
fetch_and_deploy_gh_release "filebrowser-quantum" "gtsteffaniak/filebrowser" "singlefile" "latest" "/usr/local/bin" "linux-$(arch_resolve)-filebrowser"
mv -f /usr/local/bin/filebrowser-quantum "$INSTALL_PATH"
$PKG_MANAGER curl ffmpeg &>/dev/null
curl -fsSL https://github.com/gtsteffaniak/filebrowser/releases/latest/download/linux-amd64-filebrowser -o "$TMP_BIN"
chmod +x "$TMP_BIN"
mv -f "$TMP_BIN" /usr/local/bin/filebrowser
msg_ok "Installed ${APP}"
msg_info "Preparing configuration directory"
@@ -149,7 +167,7 @@ chown root:root /usr/local/community-scripts
chmod 755 /usr/local/community-scripts
msg_ok "Directory prepared"
echo -n "${TAB}Use No Authentication? (y/N): "
echo -n "Use No Authentication? (y/N): "
read -r noauth_prompt
# === YAML CONFIG GENERATION ===
@@ -233,9 +251,9 @@ depend() {
}
EOF
chmod +x "$SERVICE_PATH"
$STD rc-update add filebrowser default
$STD rc-service filebrowser start
rc-update add filebrowser default &>/dev/null
rc-service filebrowser start &>/dev/null
fi
msg_ok "Service created successfully"
msg_ok "${APP} is reachable at: ${BL}http://${IP}:${PORT}${CL}"
echo -e "${CM} ${GN}${APP} is reachable at: ${BL}http://$IP:$PORT${CL}"
+77 -52
View File
@@ -5,40 +5,53 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://filebrowser.org/ | Github: https://github.com/filebrowser/filebrowser
function header_info {
clear
cat <<"EOF"
_______ __ ____
/ ____(_) /__ / __ )_________ _ __________ _____
/ /_ / / / _ \/ __ / ___/ __ \ | /| / / ___/ _ \/ ___/
/ __/ / / / __/ /_/ / / / /_/ / |/ |/ (__ ) __/ /
/_/ /_/_/\___/_____/_/ \____/|__/|__/____/\___/_/
EOF
}
YW=$(echo "\033[33m")
GN=$(echo "\033[1;92m")
RD=$(echo "\033[01;31m")
BL=$(echo "\033[36m")
CL=$(echo "\033[m")
CM="${GN}✔️${CL}"
CROSS="${RD}✖️${CL}"
INFO="${BL}${CL}"
APP="FileBrowser"
APP_TYPE="addon"
INSTALL_PATH="/usr/local/bin/filebrowser"
DB_PATH="/usr/local/community-scripts/filebrowser.db"
DEFAULT_PORT=8080
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "filebrowser" "addon"
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
# Get first non-loopback IP & Detect primary network interface dynamically
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
header_info
get_lxc_ip
IP="$LOCAL_IP"
[[ -z "$IP" ]] && IP=$(hostname -I | awk '{print $1}')
[[ -z "$IP" ]] && IP="127.0.0.1"
# Proxmox Host Warning
if [[ -d "/etc/pve" ]]; then
msg_warn "Running this addon directly on the Proxmox host is not recommended!"
msg_warn "Only the boot disk will be visible — passthrough drives will not be indexed."
msg_warn "This causes incorrect disk usage stats and incomplete file browsing."
msg_warn "Run this addon inside an LXC or VM instead and mount your drives there."
echo -e "${RD}⚠️ Warning: Running this addon directly on the Proxmox host is not recommended!${CL}"
echo -e "${YW} Only the boot disk will be visible — passthrough drives will not be indexed.${CL}"
echo -e "${YW} This causes incorrect disk usage stats and incomplete file browsing.${CL}"
echo -e "${YW} Run this addon inside an LXC or VM instead and mount your drives there.${CL}"
echo ""
echo -n "${TAB}Continue anyway on the Proxmox host? (y/N): "
echo -n "Continue anyway on the Proxmox host? (y/N): "
read -r host_confirm
if [[ ! "${host_confirm,,}" =~ ^(y|yes)$ ]]; then
msg_error "Aborted."
echo -e "${YW}Aborted.${CL}"
exit 0
fi
fi
@@ -51,59 +64,71 @@ if [[ -f "/etc/alpine-release" ]]; then
elif [[ -f "/etc/debian_version" ]]; then
OS="Debian"
SERVICE_PATH="/etc/systemd/system/filebrowser.service"
PKG_MANAGER="apt install -y"
PKG_MANAGER="apt-get install -y"
else
msg_error "Unsupported OS detected. Exiting."
echo -e "${CROSS} Unsupported OS detected. Exiting."
exit 238
fi
header_info
function msg_info() {
local msg="$1"
echo -e "${INFO} ${YW}${msg}...${CL}"
}
function msg_ok() {
local msg="$1"
echo -e "${CM} ${GN}${msg}${CL}"
}
function msg_error() {
local msg="$1"
echo -e "${CROSS} ${RD}${msg}${CL}"
}
if [ -f "$INSTALL_PATH" ]; then
msg_warn "${APP} is already installed."
echo -e "${YW}⚠️ ${APP} is already installed.${CL}"
read -r -p "Would you like to uninstall ${APP}? (y/N): " uninstall_prompt
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Uninstalling ${APP}"
if [[ "$OS" == "Debian" ]]; then
systemctl disable --now filebrowser.service &>/dev/null || true
systemctl disable --now filebrowser.service &>/dev/null
rm -f "$SERVICE_PATH"
else
rc-service filebrowser stop &>/dev/null || true
rc-update del filebrowser &>/dev/null || true
rc-service filebrowser stop &>/dev/null
rc-update del filebrowser &>/dev/null
rm -f "$SERVICE_PATH"
fi
rm -f "$INSTALL_PATH" "$DB_PATH" "$HOME/.filebrowser"
rm -f "$INSTALL_PATH" "$DB_PATH"
msg_ok "${APP} has been uninstalled."
exit 0
fi
read -r -p "Would you like to update ${APP}? (y/N): " update_prompt
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
if check_for_gh_release "filebrowser" "filebrowser/filebrowser"; then
msg_info "Updating ${APP}"
fetch_and_deploy_gh_release "filebrowser" "filebrowser/filebrowser" "prebuild" "latest" "/opt/filebrowser-dist" "linux-$(arch_resolve)-filebrowser.tar.gz"
install -m 755 /opt/filebrowser-dist/filebrowser "$INSTALL_PATH"
rm -rf /opt/filebrowser-dist
msg_ok "Updated ${APP}"
fi
msg_info "Updating ${APP}"
if ! command -v curl &>/dev/null; then $PKG_MANAGER curl &>/dev/null; fi
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz" | tar -xzv -C /usr/local/bin &>/dev/null
chmod +x "$INSTALL_PATH"
msg_ok "Updated ${APP}"
exit 0
else
msg_warn "Update skipped. Exiting."
echo -e "${YW}⚠️ Update skipped. Exiting.${CL}"
exit 0
fi
fi
msg_warn "${APP} is not installed."
echo -e "${YW}⚠️ ${APP} is not installed.${CL}"
read -r -p "Enter port number (Default: ${DEFAULT_PORT}): " PORT
PORT=${PORT:-$DEFAULT_PORT}
read -r -p "Would you like to install ${APP}? (y/n): " install_prompt
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Installing ${APP} on ${OS}"
$STD $PKG_MANAGER \
tar \
curl
fetch_and_deploy_gh_release "filebrowser" "filebrowser/filebrowser" "prebuild" "latest" "/opt/filebrowser-dist" "linux-$(arch_resolve)-filebrowser.tar.gz"
install -m 755 /opt/filebrowser-dist/filebrowser "$INSTALL_PATH"
rm -rf /opt/filebrowser-dist
$PKG_MANAGER wget tar curl &>/dev/null
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz" | tar -xzv -C /usr/local/bin &>/dev/null
chmod +x "$INSTALL_PATH"
msg_ok "Installed ${APP}"
msg_info "Creating FileBrowser directory"
@@ -119,19 +144,19 @@ if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
if [[ "${auth_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Configuring No Authentication"
cd /usr/local/community-scripts
$STD filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH"
$STD filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH"
$STD filebrowser config set --auth.method=noauth --database "$DB_PATH"
filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
filebrowser config set --auth.method=noauth --database "$DB_PATH" &>/dev/null
if ! filebrowser users update 1 --perm.admin --database "$DB_PATH" &>/dev/null; then
$STD filebrowser users add admin community-scripts.org --perm.admin --database "$DB_PATH"
filebrowser users add admin community-scripts.org --perm.admin --database "$DB_PATH" &>/dev/null
fi
msg_ok "No Authentication configured"
else
msg_info "Setting up default authentication"
cd /usr/local/community-scripts
$STD filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH"
$STD filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH"
$STD filebrowser users add admin community-scripts.org --perm.admin --database "$DB_PATH"
filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
filebrowser users add admin community-scripts.org --perm.admin --database "$DB_PATH" &>/dev/null
msg_ok "Default authentication configured (admin:community-scripts.org)"
fi
@@ -169,13 +194,13 @@ depend() {
}
EOF
chmod +x "$SERVICE_PATH"
$STD rc-update add filebrowser default
$STD rc-service filebrowser start
rc-update add filebrowser default &>/dev/null
rc-service filebrowser start &>/dev/null
fi
msg_ok "Service created successfully"
msg_ok "${APP} is reachable at: ${BL}http://${IP}:${PORT}${CL}"
echo -e "${CM} ${GN}${APP} is reachable at: ${BL}http://$IP:$PORT${CL}"
else
msg_warn "Installation skipped. Exiting."
echo -e "${YW}⚠️ Installation skipped. Exiting.${CL}"
exit 0
fi
+51 -32
View File
@@ -5,37 +5,55 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://nicolargo.github.io/glances/ | Github: https://github.com/nicolargo/glances
APP="Glances"
APP_TYPE="addon"
function header_info {
clear
cat <<"EOF"
________
/ ____/ /___ _____ ________ _____
/ / __/ / __ `/ __ \/ ___/ _ \/ ___/
/ /_/ / / /_/ / / / / /__/ __(__ )
\____/_/\__,_/_/ /_/\___/\___/____/
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
EOF
}
APP="Glances"
YW=$(echo "\033[33m")
GN=$(echo "\033[1;92m")
RD=$(echo "\033[01;31m")
BL=$(echo "\033[36m")
CL=$(echo "\033[m")
CM="${GN}✔️${CL}"
CROSS="${RD}✖️${CL}"
INFO="${BL}${CL}"
function msg_info() { echo -e "${INFO} ${YW}$1...${CL}"; }
function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; }
function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "glances" "addon"
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
header_info
get_lxc_ip
IP="$LOCAL_IP"
get_lxc_ip() {
if command -v hostname >/dev/null 2>&1 && hostname -I 2>/dev/null; then
hostname -I | awk '{print $1}'
elif command -v ip >/dev/null 2>&1; then
ip -4 addr show scope global | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1
else
echo "127.0.0.1"
fi
}
IP=$(get_lxc_ip)
install_glances_debian() {
msg_info "Installing dependencies"
$STD apt update
$STD apt install -y \
gcc \
lm-sensors \
wireless-tools \
curl
apt-get update >/dev/null 2>&1
apt-get install -y gcc lm-sensors wireless-tools curl >/dev/null 2>&1
msg_ok "Installed dependencies"
msg_info "Setting up Python + uv"
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
setup_uv PYTHON_VERSION="3.12"
msg_ok "Setup Python + uv"
@@ -43,10 +61,10 @@ install_glances_debian() {
cd /opt
mkdir -p glances
cd glances
$STD uv venv --clear
uv venv --clear
source .venv/bin/activate >/dev/null 2>&1
$STD uv pip install --upgrade pip wheel setuptools
$STD uv pip install "glances[web]"
uv pip install --upgrade pip wheel setuptools >/dev/null 2>&1
uv pip install "glances[web]" >/dev/null 2>&1
deactivate
msg_ok "Installed $APP"
@@ -68,7 +86,7 @@ EOF
systemctl enable -q --now glances
msg_ok "Created systemd service"
msg_ok "$APP is now running at: http://${IP}:61208"
echo -e "\n$APP is now running at: http://$IP:61208\n"
}
# update on Debian/Ubuntu
@@ -80,7 +98,7 @@ update_glances_debian() {
msg_info "Updating $APP"
cd /opt/glances
source .venv/bin/activate
$STD uv pip install --upgrade "glances[web]"
uv pip install --upgrade "glances[web]" >/dev/null 2>&1
deactivate
systemctl restart glances
msg_ok "Updated successfully!"
@@ -98,13 +116,14 @@ uninstall_glances_debian() {
# install on Alpine
install_glances_alpine() {
msg_info "Installing dependencies"
$STD apk update
apk update >/dev/null 2>&1
$STD apk add --no-cache \
gcc musl-dev linux-headers python3-dev \
python3 py3-pip py3-virtualenv lm-sensors wireless-tools curl
python3 py3-pip py3-virtualenv lm-sensors wireless-tools curl >/dev/null 2>&1
msg_ok "Installed dependencies"
msg_info "Setting up Python + uv"
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
setup_uv PYTHON_VERSION="3.12"
msg_ok "Setup Python + uv"
@@ -112,10 +131,10 @@ install_glances_alpine() {
cd /opt
mkdir -p glances
cd glances
$STD uv venv --clear
uv venv --clear
source .venv/bin/activate
$STD uv pip install --upgrade pip wheel setuptools
$STD uv pip install "glances[web]"
uv pip install --upgrade pip wheel setuptools >/dev/null 2>&1
uv pip install "glances[web]" >/dev/null 2>&1
deactivate
msg_ok "Installed $APP"
@@ -146,7 +165,7 @@ update_glances_alpine() {
msg_info "Updating $APP"
cd /opt/glances
source .venv/bin/activate
$STD uv pip install --upgrade "glances[web]"
uv pip install --upgrade "glances[web]" >/dev/null 2>&1
deactivate
rc-service glances restart
msg_ok "Updated successfully!"
+26 -5
View File
@@ -7,8 +7,8 @@
if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt update >/dev/null 2>&1
apt install -y curl >/dev/null 2>&1
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -32,6 +32,21 @@ DEFAULT_PORT=3000
# Initialize all core functions (colors, formatting, icons, $STD mode)
load_functions
# ==============================================================================
# HEADER
# ==============================================================================
function header_info {
clear
cat <<"EOF"
____ _ __ ____
/ _/___ ___ ____ ___ (_)____/ /_ / __ \_________ _ ____ __
/ // __ `__ \/ __ `__ \/ / ___/ __ \______/ /_/ / ___/ __ \| |/_/ / / /
_/ // / / / / / / / / / / / /__/ / / /_____/ ____/ / / /_/ /> </ /_/ /
/___/_/ /_/ /_/_/ /_/ /_/_/\___/_/ /_/ /_/ /_/ \____/_/|_|\__, /
/____/
EOF
}
# ==============================================================================
# OS DETECTION
# ==============================================================================
@@ -68,13 +83,19 @@ function update() {
systemctl stop immich-proxy.service &>/dev/null || true
msg_ok "Stopped service"
BACKUP_DIR="/opt/immich-public-proxy_backup"
create_backup "$CONFIG_PATH"/.env "$CONFIG_PATH"/config.json
msg_info "Backing up configuration"
cp "$CONFIG_PATH"/.env /tmp/ipp.env.bak 2>/dev/null || true
cp "$CONFIG_PATH"/config.json /tmp/ipp.config.json.bak 2>/dev/null || true
msg_ok "Backed up configuration"
NODE_VERSION="24" setup_nodejs
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Immich Public Proxy" "alangrainger/immich-public-proxy" "tarball" "latest" "$INSTALL_PATH"
restore_backup
msg_info "Restoring configuration"
cp /tmp/ipp.env.bak "$CONFIG_PATH"/.env 2>/dev/null || true
cp /tmp/ipp.config.json.bak "$CONFIG_PATH"/config.json 2>/dev/null || true
rm -f /tmp/ipp.*.bak
msg_ok "Restored configuration"
msg_info "Installing dependencies"
cd "$CONFIG_PATH"
+24 -5
View File
@@ -7,8 +7,8 @@
if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt update >/dev/null 2>&1
apt install -y curl >/dev/null 2>&1
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -32,6 +32,21 @@ DEFAULT_PORT=3000
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
# ==============================================================================
# HEADER
# ==============================================================================
function header_info {
clear
cat <<"EOF"
__ ____ __ __
/ /__ / / /_ _______/ /_____ _/ /_
__ / / _ \/ / / / / / ___/ __/ __ `/ __/
/ /_/ / __/ / / /_/ (__ ) /_/ /_/ / /_
\____/\___/_/_/\__, /____/\__/\__,_/\__/
/____/
EOF
}
# ==============================================================================
# OS DETECTION
# ==============================================================================
@@ -87,12 +102,16 @@ function update() {
systemctl stop jellystat.service &>/dev/null || true
msg_ok "Stopped service"
BACKUP_DIR="/opt/jellystat_backup"
create_backup "$CONFIG_PATH"
msg_info "Backing up configuration"
cp "$CONFIG_PATH" /tmp/jellystat.env.bak 2>/dev/null || true
msg_ok "Backed up configuration"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "jellystat" "CyferShepard/Jellystat" "tarball" "latest" "$INSTALL_PATH"
restore_backup
msg_info "Restoring configuration"
cp /tmp/jellystat.env.bak "$CONFIG_PATH" 2>/dev/null || true
rm -f /tmp/jellystat.env.bak
msg_ok "Restored configuration"
msg_info "Installing dependencies"
cd "$INSTALL_PATH"
+78 -34
View File
@@ -5,22 +5,6 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.netdata.cloud/ | Github: https://github.com/netdata/netdata
APP="Netdata"
APP_TYPE="addon"
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "netdata" "addon"
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
function header_info {
clear
cat <<"EOF"
@@ -33,6 +17,63 @@ function header_info {
EOF
}
YW=$(echo "\033[33m")
BL=$(echo "\033[36m")
RD=$(echo "\033[01;31m")
GN=$(echo "\033[1;92m")
CL=$(echo "\033[m")
BFR="\\r\\033[K"
HOLD="-"
CM="${GN}${CL}"
silent() { "$@" >/dev/null 2>&1; }
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "netdata" "addon"
set -e
header_info
echo "Loading..."
function msg_info() {
local msg="$1"
echo -ne " ${HOLD} ${YW}${msg}..."
}
function msg_ok() {
local msg="$1"
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
}
function msg_error() { echo -e "${RD}$1${CL}"; }
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
# Supported: Proxmox VE 8.0.x 8.9.x and 9.09.x
pve_check() {
local PVE_VER
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
# Check for Proxmox VE 8.x: allow 8.08.9
if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then
local MINOR="${BASH_REMATCH[1]}"
if ((MINOR < 0 || MINOR > 9)); then
msg_error "This version of Proxmox VE is not supported."
msg_error "Supported: Proxmox VE version 8.0 8.9"
exit 105
fi
return 0
fi
# Check for Proxmox VE 9.x: allow 9.09.x
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
return 0
fi
# All other unsupported versions
msg_error "This version of Proxmox VE is not supported."
msg_error "Supported versions: Proxmox VE 8.0 8.9 or 9.09.x"
exit 105
}
detect_codename() {
source /etc/os-release
if [[ "$ID" != "debian" ]]; then
@@ -58,7 +99,7 @@ get_latest_repo_pkg() {
install() {
header_info
while true; do
read -r -p "Are you sure you want to install ${APP} on Proxmox VE host. Proceed(y/n)? " yn
read -p "Are you sure you want to install NetData on Proxmox VE host. Proceed(y/n)? " yn
case $yn in
[Yy]*) break ;;
[Nn]*) exit ;;
@@ -66,53 +107,56 @@ install() {
esac
done
read -r -p "Verbose mode? <y/N> " prompt
[[ ${prompt,,} =~ ^(y|yes)$ ]] && STD="" || STD="silent"
CODENAME=$(detect_codename)
REPO_URL="https://repo.netdata.cloud/repos/repoconfig/debian/${CODENAME}/"
msg_info "Setting up repository"
$STD apt install -y debian-keyring
$STD apt-get install -y debian-keyring
PKG=$(get_latest_repo_pkg "$REPO_URL")
if [[ -z "$PKG" ]]; then
msg_error "Could not find netdata-repo package for Debian $CODENAME"
exit 237
fi
TMP_DEB=$(mktemp --suffix=.deb)
curl -fsSL "${REPO_URL}${PKG}" -o "$TMP_DEB"
$STD dpkg -i "$TMP_DEB"
rm -f "$TMP_DEB"
curl -fsSL "${REPO_URL}${PKG}" -o "$PKG"
$STD dpkg -i "$PKG"
rm -f "$PKG"
msg_ok "Set up repository"
msg_info "Installing ${APP}"
$STD apt update
$STD apt install -y netdata
msg_ok "Installed ${APP}"
msg_info "Installing Netdata"
$STD apt-get update
$STD apt-get install -y netdata
msg_ok "Installed Netdata"
msg_ok "Completed successfully!\n"
get_lxc_ip
echo -e "\n${APP} should be reachable at${BL} http://${LOCAL_IP}:19999 ${CL}\n"
echo -e "\n Netdata should be reachable at${BL} http://$(hostname -I | awk '{print $1}'):19999 ${CL}\n"
}
uninstall() {
header_info
read -r -p "Verbose mode? <y/N> " prompt
[[ ${prompt,,} =~ ^(y|yes)$ ]] && STD="" || STD="silent"
msg_info "Uninstalling ${APP}"
msg_info "Uninstalling Netdata"
systemctl stop netdata || true
rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/netdata/go.d
rm -rf /etc/apt/trusted.gpg.d/netdata-archive-keyring.gpg /etc/apt/sources.list.d/netdata.list
$STD apt remove --purge -y netdata netdata-repo
$STD apt-get remove --purge -y netdata netdata-repo
systemctl daemon-reload
$STD apt autoremove -y
$STD userdel netdata || true
msg_ok "Uninstalled ${APP}"
msg_ok "Uninstalled Netdata"
msg_ok "Completed successfully!\n"
}
header_info
pve_check
OPTIONS=(Install "Install ${APP} on Proxmox VE"
Uninstall "Uninstall ${APP} from Proxmox VE")
OPTIONS=(Install "Install NetData on Proxmox VE"
Uninstall "Uninstall NetData from Proxmox VE")
CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP}" \
CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "NetData" \
--menu "Select an option:" 10 58 2 "${OPTIONS[@]}" 3>&1 1>&2 2>&3)
case $CHOICE in
+49 -102
View File
@@ -5,120 +5,67 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://docs.olivetin.app/ | Github: https://github.com/OliveTin/OliveTin
APP="OliveTin"
APP_TYPE="addon"
function header_info {
clear
cat <<"EOF"
____ ___ _______
/ __ \/ (_) _____/_ __(_)___
/ / / / / / | / / _ \/ / / / __ \
/ /_/ / / /| |/ / __/ / / / / / /
\____/_/_/ |___/\___/_/ /_/_/ /_/
EOF
}
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
IP=$(hostname -I | awk '{print $1}')
YW=$(echo "\033[33m")
BL=$(echo "\033[36m")
GN=$(echo "\033[1;92m")
CL=$(echo "\033[m")
BFR="\\r\\033[K"
HOLD="-"
CM="${GN}${CL}"
APP="OliveTin"
hostname="$(hostname)"
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "olivetin" "addon"
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
set-e
header_info
ensure_usr_local_bin_persist
get_lxc_ip
IP="$LOCAL_IP"
# ==============================================================================
# UNINSTALL
# ==============================================================================
function uninstall() {
msg_info "Uninstalling ${APP}"
systemctl disable --now OliveTin &>/dev/null || true
$STD apt remove -y olivetin
rm -f "$HOME/.olivetin"
msg_ok "${APP} has been uninstalled"
}
# ==============================================================================
# UPDATE
# ==============================================================================
function update() {
if check_for_gh_release "olivetin" "OliveTin/OliveTin"; then
msg_info "Updating ${APP}"
fetch_and_deploy_gh_release "olivetin" "OliveTin/OliveTin" "binary"
systemctl restart OliveTin
msg_ok "Updated successfully!"
exit
fi
}
# ==============================================================================
# INSTALL
# ==============================================================================
function install() {
msg_info "Installing ${APP}"
fetch_and_deploy_gh_release "olivetin" "OliveTin/OliveTin" "binary"
systemctl enable --now OliveTin &>/dev/null
msg_ok "Installed ${APP}"
msg_info "Creating update script"
ensure_usr_local_bin_persist
cat <<'EOF' >/usr/local/bin/update_olivetin
#!/usr/bin/env bash
# OliveTin Update Script
type=update bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/olivetin.sh)"
EOF
chmod +x /usr/local/bin/update_olivetin
msg_ok "Created update script (/usr/local/bin/update_olivetin)"
msg_ok "Completed successfully!\n"
echo -e "${APP} should be reachable by going to the following URL.
${BL}http://${IP}:1337${CL} \n"
}
# ==============================================================================
# MAIN
# ==============================================================================
# Handle type=update (called from update script)
if [[ "${type:-}" == "update" ]]; then
if command -v olivetin &>/dev/null; then
update
else
msg_error "${APP} is not installed. Nothing to update."
exit 233
fi
exit 0
fi
if [[ -d "$HOME" && -f "$HOME/.olivetin" ]] || command -v olivetin &>/dev/null; then
msg_warn "${APP} is already installed."
echo -n "${TAB}Uninstall ${APP}? (y/N): "
read -r uninstall_prompt
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
uninstall
exit 0
fi
echo -n "${TAB}Update ${APP}? (y/N): "
read -r update_prompt
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
update
exit 0
fi
msg_warn "No action selected. Exiting."
exit 0
fi
while true; do
echo -n "${TAB}This will Install ${APP}. Proceed (y/n)? "
read -r yn
read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn
case $yn in
[Yy]*) break ;;
[Nn]*) exit ;;
*) echo "Please answer yes or no." ;;
esac
done
unset _HEADER_SHOWN
header_info
install
function msg_info() {
local msg="$1"
echo -ne " ${HOLD} ${YW}${msg}..."
}
function msg_ok() {
local msg="$1"
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
}
msg_info "Installing ${APP}"
if ! command -v curl &>/dev/null; then
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
curl -fsSL "https://github.com/OliveTin/OliveTin/releases/latest/download/OliveTin_linux_amd64.deb" -o $(basename "https://github.com/OliveTin/OliveTin/releases/latest/download/OliveTin_linux_amd64.deb")
dpkg -i OliveTin_linux_amd64.deb &>/dev/null
systemctl enable --now OliveTin &>/dev/null
rm OliveTin_linux_amd64.deb
msg_ok "Installed ${APP} on $hostname"
msg_ok "Completed successfully!\n"
echo -e "${APP} should be reachable by going to the following URL.
${BL}http://$IP:1337${CL} \n"
+63 -53
View File
@@ -5,26 +5,39 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.phpmyadmin.net/ | Github: https://github.com/phpmyadmin/phpmyadmin
function header_info {
clear
cat <<"EOF"
____ __ __ ___ ___ __ _
/ __ \/ /_ ____ / |/ /_ __/ | ____/ /___ ___ (_)___
/ /_/ / __ \/ __ \/ /|_/ / / / / /| |/ __ / __ `__ \/ / __ \
/ ____/ / / / /_/ / / / / /_/ / ___ / /_/ / / / / / / / / / /
/_/ /_/ /_/ .___/_/ /_/\__, /_/ |_\__,_/_/ /_/ /_/_/_/ /_/
/_/ /____/
EOF
}
YW=$(echo "\033[33m")
GN=$(echo "\033[1;92m")
RD=$(echo "\033[01;31m")
BL=$(echo "\033[36m")
CL=$(echo "\033[m")
CM="${GN}✔️${CL}"
CROSS="${RD}✖️${CL}"
INFO="${BL}${CL}"
APP="phpMyAdmin"
APP_TYPE="addon"
INSTALL_DIR_DEBIAN="/var/www/html/phpMyAdmin"
INSTALL_DIR_ALPINE="/usr/share/phpmyadmin"
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "phpmyadmin" "addon"
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
get_lxc_ip
IP="$LOCAL_IP"
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
[[ -z "$IP" ]] && IP=$(hostname -I | awk '{print $1}')
[[ -z "$IP" ]] && IP="127.0.0.1"
# Detect OS
if [[ -f "/etc/alpine-release" ]]; then
@@ -34,20 +47,24 @@ if [[ -f "/etc/alpine-release" ]]; then
INSTALL_DIR="$INSTALL_DIR_ALPINE"
elif [[ -f "/etc/debian_version" ]]; then
OS="Debian"
PKG_MANAGER_INSTALL="apt install -y"
PKG_MANAGER_INSTALL="apt-get install -y"
PKG_QUERY="dpkg -l"
INSTALL_DIR="$INSTALL_DIR_DEBIAN"
else
msg_error "Unsupported OS detected. Exiting."
echo -e "${CROSS} Unsupported OS detected. Exiting."
exit 238
fi
header_info
function msg_info() { echo -e "${INFO} ${YW}${1}...${CL}"; }
function msg_ok() { echo -e "${CM} ${GN}${1}${CL}"; }
function msg_error() { echo -e "${CROSS} ${RD}${1}${CL}"; }
function check_internet() {
if ! command -v curl &>/dev/null; then
$STD apt update
$STD apt install -y curl
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
msg_info "Checking Internet connectivity to GitHub"
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" https://github.com)
@@ -86,7 +103,7 @@ function install_php_and_modules() {
done
if [[ ${#MISSING_PACKAGES[@]} -gt 0 ]]; then
msg_info "Installing missing PHP packages: ${MISSING_PACKAGES[*]}"
if ! $STD apt update || ! $STD apt install -y "${MISSING_PACKAGES[@]}"; then
if ! apt-get update &>/dev/null || ! apt-get install -y "${MISSING_PACKAGES[@]}" &>/dev/null; then
msg_error "Failed to install required PHP modules. Exiting."
exit 237
fi
@@ -96,41 +113,30 @@ function install_php_and_modules() {
fi
else
msg_info "Installing Lighttpd and PHP for Alpine"
$STD $PKG_MANAGER_INSTALL \
lighttpd \
php \
php-fpm \
php-session \
php-json \
php-mysqli \
curl \
tar \
openssl
$PKG_MANAGER_INSTALL lighttpd php php-fpm php-session php-json php-mysqli curl tar openssl &>/dev/null
msg_ok "Installed Lighttpd and PHP"
fi
}
function install_phpmyadmin() {
msg_info "Fetching latest phpMyAdmin release from GitHub"
LATEST_VERSION_RAW=$(get_latest_github_release "phpmyadmin/phpmyadmin" false) || true
LATEST_VERSION_RAW=$(curl -s https://api.github.com/repos/phpmyadmin/phpmyadmin/releases/latest | grep tag_name | cut -d '"' -f4)
LATEST_VERSION=$(echo "$LATEST_VERSION_RAW" | sed -e 's/^RELEASE_//' -e 's/_/./g')
if [[ -z "$LATEST_VERSION" ]]; then
msg_error "Could not determine latest phpMyAdmin version from GitHub falling back to 5.2.2"
LATEST_VERSION="5.2.2"
LATEST_VERSION="RELEASE_5_2_2"
fi
msg_ok "Latest version: $LATEST_VERSION"
TARBALL_URL="https://files.phpmyadmin.net/phpMyAdmin/${LATEST_VERSION}/phpMyAdmin-${LATEST_VERSION}-all-languages.tar.gz"
msg_info "Downloading ${TARBALL_URL}"
tarball=$(mktemp)
if ! curl -fsSL "$TARBALL_URL" -o "$tarball"; then
if ! curl -fsSL "$TARBALL_URL" -o /tmp/phpmyadmin.tar.gz; then
msg_error "Download failed: $TARBALL_URL"
exit 115
fi
mkdir -p "$INSTALL_DIR"
tar xf "$tarball" --strip-components=1 -C "$INSTALL_DIR"
rm -f "$tarball"
tar xf /tmp/phpmyadmin.tar.gz --strip-components=1 -C "$INSTALL_DIR"
}
function configure_phpmyadmin() {
@@ -217,7 +223,7 @@ function uninstall_phpmyadmin() {
function update_phpmyadmin() {
msg_info "Fetching latest phpMyAdmin release from GitHub"
LATEST_VERSION_RAW=$(get_latest_github_release "phpmyadmin/phpmyadmin" false) || true
LATEST_VERSION_RAW=$(curl -s https://api.github.com/repos/phpmyadmin/phpmyadmin/releases/latest | grep tag_name | cut -d '"' -f4)
LATEST_VERSION=$(echo "$LATEST_VERSION_RAW" | sed -e 's/^RELEASE_//' -e 's/_/./g')
if [[ -z "$LATEST_VERSION" ]]; then
@@ -228,32 +234,36 @@ function update_phpmyadmin() {
TARBALL_URL="https://files.phpmyadmin.net/phpMyAdmin/${LATEST_VERSION}/phpMyAdmin-${LATEST_VERSION}-all-languages.tar.gz"
msg_info "Downloading ${TARBALL_URL}"
tarball=$(mktemp)
if ! curl -fsSL "$TARBALL_URL" -o "$tarball"; then
if ! curl -fsSL "$TARBALL_URL" -o /tmp/phpmyadmin.tar.gz; then
msg_error "Download failed: $TARBALL_URL"
exit 115
fi
BACKUP_DIR="/opt/phpmyadmin_backup"
create_backup \
"$INSTALL_DIR/config.inc.php" \
"$INSTALL_DIR/upload" \
"$INSTALL_DIR/save" \
"$INSTALL_DIR/tmp" \
"$INSTALL_DIR/themes"
BACKUP_DIR="/tmp/phpmyadmin-backup-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
BACKUP_ITEMS=("config.inc.php" "upload" "save" "tmp" "themes")
tar xf "$tarball" --strip-components=1 -C "$INSTALL_DIR"
rm -f "$tarball"
msg_info "Backing up existing phpMyAdmin data"
for item in "${BACKUP_ITEMS[@]}"; do
[[ -e "$INSTALL_DIR/$item" ]] && cp -a "$INSTALL_DIR/$item" "$BACKUP_DIR/" && echo " ↪︎ $item"
done
msg_ok "Backup completed: $BACKUP_DIR"
tar xf /tmp/phpmyadmin.tar.gz --strip-components=1 -C "$INSTALL_DIR"
msg_ok "Extracted phpMyAdmin $LATEST_VERSION"
restore_backup
msg_info "Restoring preserved files"
for item in "${BACKUP_ITEMS[@]}"; do
[[ -e "$BACKUP_DIR/$item" ]] && cp -a "$BACKUP_DIR/$item" "$INSTALL_DIR/" && echo " ↪︎ $item restored"
done
msg_ok "Restoration completed"
configure_phpmyadmin
}
if is_phpmyadmin_installed; then
msg_warn "${APP} is already installed at ${INSTALL_DIR}."
echo -e "${YW}⚠️ ${APP} is already installed at ${INSTALL_DIR}.${CL}"
read -r -p "Would you like to Update (1), Uninstall (2) or Cancel (3)? [1/2/3]: " action
action="${action//[[:space:]]/}"
case "$action" in
@@ -265,11 +275,11 @@ if is_phpmyadmin_installed; then
uninstall_phpmyadmin
;;
3)
msg_warn "Action cancelled. Exiting."
echo -e "${YW}⚠️ Action cancelled. Exiting.${CL}"
exit 0
;;
*)
msg_warn "Invalid input. Exiting."
echo -e "${YW}⚠️ Invalid input. Exiting.${CL}"
exit 112
;;
esac
@@ -282,12 +292,12 @@ else
install_phpmyadmin
configure_phpmyadmin
if [[ "$OS" == "Debian" ]]; then
msg_ok "${APP} is reachable at: ${BL}http://${IP}/phpMyAdmin${CL}"
echo -e "${CM} ${GN}${APP} is reachable at: ${BL}http://${IP}/phpMyAdmin${CL}"
else
msg_ok "${APP} is reachable at: ${BL}http://${IP}/${CL}"
echo -e "${CM} ${GN}${APP} is reachable at: ${BL}http://${IP}/${CL}"
fi
else
msg_warn "Installation skipped. Exiting."
echo -e "${YW}⚠️ Installation skipped. Exiting.${CL}"
exit 0
fi
fi
+47 -38
View File
@@ -5,30 +5,40 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://pyenv.run/ | Github: https://github.com/pyenv/pyenv
APP="pyenv"
APP_TYPE="addon"
set -e
YW=$(echo "\033[33m")
RD=$(echo "\033[01;31m")
BL=$(echo "\033[36m")
GN=$(echo "\033[1;92m")
CL=$(echo "\033[m")
CM="${GN}${CL}"
CROSS="${RD}${CL}"
BFR="\\r\\033[K"
HOLD="-"
function msg_info() {
local msg="$1"
echo -ne " ${HOLD} ${YW}${msg}..."
}
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
function msg_ok() {
local msg="$1"
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
}
function msg_error() {
local msg="$1"
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
}
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "pyenv" "addon"
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
if command -v pveversion >/dev/null 2>&1; then
msg_error "Can't Install on Proxmox "
exit 1
exit
fi
get_lxc_ip
msg_info "Installing ${APP}"
$STD apt update
$STD apt install -y \
msg_info "Installing pyenv"
apt-get install -y \
make \
build-essential \
libjpeg-dev \
@@ -52,18 +62,18 @@ $STD apt install -y \
libopenjp2-7 \
libtiff5 \
libturbojpeg0-dev \
liblzma-dev
liblzma-dev &>/dev/null
$STD git clone https://github.com/pyenv/pyenv.git ~/.pyenv
set +Eeuo pipefail
git clone https://github.com/pyenv/pyenv.git ~/.pyenv &>/dev/null
set +e
echo 'export PYENV_ROOT="$HOME/.pyenv"' >>~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >>~/.bashrc
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >>~/.bashrc
msg_ok "Installed ${APP}"
msg_ok "Installed pyenv"
. ~/.bashrc
set -Eeuo pipefail
set -e
msg_info "Installing Python 3.11.1"
$STD pyenv install 3.11.1
pyenv install 3.11.1 &>/dev/null
pyenv global 3.11.1
msg_ok "Installed Python 3.11.1"
read -r -p "Would you like to install Home Assistant Beta? <y/N> " prompt
@@ -85,13 +95,13 @@ EOF
cd /srv/homeassistant
python3 -m venv .
source bin/activate
$STD python3 -m pip install wheel
$STD pip3 install --upgrade pip
$STD pip3 install psycopg2-binary
$STD pip3 install --pre homeassistant
python3 -m pip install wheel &>/dev/null
pip3 install --upgrade pip &>/dev/null
pip3 install psycopg2-binary &>/dev/null
pip3 install --pre homeassistant &>/dev/null
systemctl enable homeassistant &>/dev/null
msg_ok "Installed Home Assistant Beta"
echo -e " Go to ${LOCAL_IP}:8123"
echo -e " Go to $(hostname -I | awk '{print $1}'):8123"
hass
fi
@@ -102,9 +112,9 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
cd /srv/esphome
python3 -m venv .
source bin/activate
$STD python3 -m pip install wheel
$STD pip3 install --upgrade pip
$STD pip3 install --pre esphome
python3 -m pip install wheel &>/dev/null
pip3 install --upgrade pip &>/dev/null
pip3 install --pre esphome &>/dev/null
cat <<EOF >/srv/esphome/start.sh
#!/usr/bin/env bash
@@ -133,26 +143,25 @@ WantedBy=multi-user.target
EOF
systemctl enable --now esphomedashboard &>/dev/null
msg_ok "Installed ESPHome Beta"
echo -e " Go to ${LOCAL_IP}:6052"
echo -e " Go to $(hostname -I | awk '{print $1}'):6052"
exec $SHELL
fi
read -r -p "Would you like to install Matter-Server (Beta)? <y/N> " prompt
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Installing Matter Server"
$STD apt install -y \
apt-get install -y \
libcairo2-dev \
libjpeg62-turbo-dev \
libgirepository1.0-dev \
libpango1.0-dev \
libgif-dev \
g++
$STD python3 -m pip install wheel
$STD pip3 install --upgrade pip
$STD pip install python-matter-server[server]
g++ &>/dev/null
python3 -m pip install wheel
pip3 install --upgrade pip
pip install python-matter-server[server]
msg_ok "Installed Matter Server"
echo -e "Start server > python -m matter_server.server"
fi
msg_ok "\nFinished\n"
exec $SHELL
+39 -31
View File
@@ -5,22 +5,6 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.webmin.com/ | Github: https://github.com/webmin/webmin
APP="Webmin"
APP_TYPE="addon"
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "webmin" "addon"
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
function header_info {
clear
cat <<"EOF"
@@ -31,27 +15,51 @@ function header_info {
EOF
}
set -eEuo pipefail
YW=$(echo "\033[33m")
BL=$(echo "\033[36m")
BGN=$(echo "\033[4;92m")
GN=$(echo "\033[1;92m")
DGN=$(echo "\033[32m")
CL=$(echo "\033[m")
CM="${GN}✓${CL}"
BFR="\\r\\033[K"
HOLD="-"
msg_info() {
local msg="$1"
echo -ne " ${HOLD} ${YW}${msg}..."
}
msg_ok() {
local msg="$1"
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
}
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "webmin" "addon"
header_info
whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP} Installer" --yesno "This Will Install ${APP} on this LXC Container. Proceed?" 10 58
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Webmin Installer" --yesno "This Will Install Webmin on this LXC Container. Proceed?" 10 58
msg_info "Installing Prerequisites"
$STD apt update
$STD apt install -y \
libnet-ssleay-perl \
libauthen-pam-perl \
libio-pty-perl \
unzip \
shared-mime-info \
curl
apt update &>/dev/null
apt-get -y install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info curl &>/dev/null
msg_ok "Installed Prerequisites"
msg_info "Installing ${APP}"
fetch_and_deploy_gh_release "webmin" "webmin/webmin" "binary" "latest" "/opt/webmin" "webmin_*_all.deb"
LATEST=$(curl -fsSL https://api.github.com/repos/webmin/webmin/releases/latest | grep '"tag_name":' | cut -d'"' -f4)
msg_info "Downloading Webmin"
curl -fsSL "https://github.com/webmin/webmin/releases/download/$LATEST/webmin_${LATEST}_all.deb" -o $(basename "https://github.com/webmin/webmin/releases/download/$LATEST/webmin_${LATEST}_all.deb")
msg_ok "Downloaded Webmin"
msg_info "Installing Webmin"
dpkg -i webmin_${LATEST}_all.deb &>/dev/null
/usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null
msg_ok "Installed ${APP}"
get_lxc_ip
echo -e "Successfully Installed!! ${APP} should be reachable by going to ${BL}https://${LOCAL_IP}:10000${CL}"
rm -rf /root/webmin_${LATEST}_all.deb
msg_ok "Installed Webmin"
IP=$(hostname -I | cut -f1 -d ' ')
echo -e "Successfully Installed!! Webmin should be reachable by going to ${BL}https://${IP}:10000${CL}"