From 996ad5aa0eb43c3dd828f60f20e0013238765437 Mon Sep 17 00:00:00 2001 From: Jason Green Date: Thu, 26 Jun 2025 21:16:02 -0700 Subject: [PATCH 001/463] Added install script for Scraparr - a Prometheus exporter for *arr applications. --- ct/scraparr.sh | 61 +++++++++++++++++++++++++++ frontend/public/json/scraparr.json | 40 ++++++++++++++++++ install/scraparr-install.sh | 68 ++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 ct/scraparr.sh create mode 100644 frontend/public/json/scraparr.json create mode 100644 install/scraparr-install.sh diff --git a/ct/scraparr.sh b/ct/scraparr.sh new file mode 100644 index 00000000..04ca13ef --- /dev/null +++ b/ct/scraparr.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: JasonGreenC +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/thecfu/scraparr + +APP="Scraparr" +var_tags="${var_tags:-arr;monitoring}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-1024}" +var_disk="${var_disk:-4}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +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/scraparr/ ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + msg_info "Updating ${APP}" + RELEASE=$(curl -fsSL https://api.github.com/repos/thecfu/scraparr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + msg_info "Stopping Services" + systemctl stop scraparr + msg_ok "Services Stopped" + + msg_info "Updating ${APP} to v${RELEASE}" + temp_file=$(mktemp) + curl -fsSL "https://github.com/thecfu/scraparr/archive/refs/tags/v2.2.2.tar.gz" -o "$temp_file" + tar -zxf "$temp_file" + mv "scrappar-${RELEASE}" /opt/scrappar + pip -q install -r /opt/scrappar/src/scrappar/requirements.txt --root-user-action=ignore + msg_ok "Updated ${APP}" + + msg_info "Starting Service" + systemctl start scraparr + msg_ok "Started Service" + else + msg_ok "No update required. ${APP} is already at v${RELEASE}" + 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}http://${IP}:7100${CL}" diff --git a/frontend/public/json/scraparr.json b/frontend/public/json/scraparr.json new file mode 100644 index 00000000..4502bf2a --- /dev/null +++ b/frontend/public/json/scraparr.json @@ -0,0 +1,40 @@ +{ + "name": "Scraparr", + "slug": "scraparr", + "categories": [ + 14 + ], + "date_created": "2024-05-02", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 8989, + "documentation": null, + "website": "https://github.com/thecfu/scraparr", + "logo": "https://github.com/thecfu/scraparr/raw/main/.github/assets/logos/scraparr_logo.svg", + "config_path": "/scraparr/config/config.yaml", + "description": "Scraparr is a Prometheus exporter for the *arr suite (Sonarr, Radarr, Lidarr, etc.). It provides metrics that can be scraped by Prometheus to monitor and visualize the health and performance of your *arr applications.", + "install_methods": [ + { + "type": "default", + "script": "ct/scraparr.sh", + "resources": { + "cpu": 2, + "ram": 1024, + "hdd": 4, + "os": "debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [ + { + "text": "Edit config file then restart the scraparr service: `systemctl restart scraparr`", + "type": "info" + } + ] +} diff --git a/install/scraparr-install.sh b/install/scraparr-install.sh new file mode 100644 index 00000000..388ab78e --- /dev/null +++ b/install/scraparr-install.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: JasonGreenC +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/thecfu/scraparr + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + python3 \ + python3-pip + +msg_ok "Installed Dependencies" + +msg_info "Installing Scraparr" +temp_file=$(mktemp) +RELEASE=$(curl -fsSL https://api.github.com/repos/thecfu/scraparr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +echo "${RELEASE}" >"/opt/Scraparr_version.txt" +curl -fsSL "https://github.com/thecfu/scraparr/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file" +tar -zxf "$temp_file" +mv "scraparr-${RELEASE}" /opt/scraparr +pip -q install -r /opt/scraparr/src/scraparr/requirements.txt --root-user-action=ignore +chmod -R 755 /opt/scraparr +mkdir /scraparr && mkdir /scraparr/config +mv /opt/scraparr/config.yaml /scraparr/config/config.yaml +chmod -R 755 /scraparr +msg_ok "Installed Scraparr" + +msg_info "Creating Service" +cat </etc/systemd/system/scraparr.service +[Unit] +Description=Scraparr +Wants=network-online.target +After=network.target + +[Service] +Type=simple +ExecStart=/usr/bin/python3 -m scraparr.scraparr +WorkingDirectory=/opt/scraparr/src +User=root +Restart=always + +[Install] +WantedBy=multi-user.target + +EOF + +systemctl daemon-reload +systemctl enable -q --now scraparr + +msg_ok "Configured Service" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -f "$temp_file" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 940b56bfff848b118352dcb5a45837577a3375f3 Mon Sep 17 00:00:00 2001 From: Joseph Stubberfield Date: Fri, 27 Jun 2025 19:40:14 +1000 Subject: [PATCH 002/463] Initial commit --- ct/librespeed-rust.sh | 64 +++++++++++++++++++++++ frontend/public/json/librespeed-rust.json | 35 +++++++++++++ install/librespeed-rust-install.sh | 41 +++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 ct/librespeed-rust.sh create mode 100644 frontend/public/json/librespeed-rust.json create mode 100644 install/librespeed-rust-install.sh diff --git a/ct/librespeed-rust.sh b/ct/librespeed-rust.sh new file mode 100644 index 00000000..c6664b5c --- /dev/null +++ b/ct/librespeed-rust.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: Joseph Stubberfield (stubbers) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/librespeed/speedtest-rust + +APP="Librespeed Rust" +var_tags="${var_tags:-network}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-512}" +var_disk="${var_disk:-4}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +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 /var/lib/librespeed-rs ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + RELEASE=$(curl -fsSL https://api.github.com/repos/librespeed/speedtest-rust/releases/latest | grep '"tag_name"' | sed -E 's/.*"tag_name": "v([^"]+).*/\1/') + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + msg_info "Stopping Services" + systemctl stop librespeed-rs + msg_ok "Services Stopped" + + msg_info "Updating ${APP} to v${RELEASE}" + $STD apt-get update + $STD apt-get -y upgrade + mv /var/lib/librespeed /var/lib/librespeed-backup + temp_file=$(mktemp) + curl -fsSL "https://github.com/librespeed/speedtest-rust/releases/download/v${RELEASE}/librespeed-rs-x86_64-unknown-linux-gnu.deb" -o "$temp_file" + $STD dpkg -u "$temp_file" + rm -rf "$temp_file" + rm -rf /var/lib/librespeed-backup + echo "${RELEASE}" >/opt/"${APPLICATION}"_version.txt + msg_ok "Updated ${APP}" + + msg_info "Starting Service" + systemctl start librespeed-rs + msg_ok "Started Service" + else + msg_ok "No update required. ${APP} is already at v${RELEASE}" + 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}http://${IP}:8080${CL}" diff --git a/frontend/public/json/librespeed-rust.json b/frontend/public/json/librespeed-rust.json new file mode 100644 index 00000000..ce067083 --- /dev/null +++ b/frontend/public/json/librespeed-rust.json @@ -0,0 +1,35 @@ +{ + "name": "Librespeed Rust", + "slug": "librespeed-rust", + "categories": [ + 4 + ], + "date_created": "2025-06-27", + "type": "ct", + "updateable": true, + "privileged": false, + "config_path": "/var/lib/librespeed-rs/configs.toml", + "interface_port": 8080, + "documentation": "https://github.com/librespeed/speedtest-rust", + "website": "https://github.com/librespeed/speedtest-rust", + "logo": "https://raw.githubusercontent.com/selfhst/icons/refs/heads/main/svg/librespeed.svg", + "description": "Librespeed is a no flash, no java, no websocket speedtest server. This community script deploys the rust version for simplicity and low resource usage.", + "install_methods": [ + { + "type": "default", + "script": "ct/librespeed.sh", + "resources": { + "cpu": 1, + "ram": 512, + "hdd": 4, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} diff --git a/install/librespeed-rust-install.sh b/install/librespeed-rust-install.sh new file mode 100644 index 00000000..bdba15c5 --- /dev/null +++ b/install/librespeed-rust-install.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: Joseph Stubberfield (stubbers) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/librespeed/speedtest-rust + +# Import Functions und Setup +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +# Setup App +msg_info "Setup ${APPLICATION}" +RELEASE=$(curl -fsSL https://api.github.com/repos/librespeed/speedtest-rust/releases/latest | grep '"tag_name"' | sed -E 's/.*"tag_name": "v([^"]+).*/\1/') +curl -fsSL -o "librespeed-rs-x86_64-unknown-linux-gnu.deb" "https://github.com/librespeed/speedtest-rust/releases/download/v${RELEASE}/librespeed-rs-x86_64-unknown-linux-gnu.deb" +$STD dpkg -i "librespeed-rs-x86_64-unknown-linux-gnu.deb" +# +# +# +echo "${RELEASE}" >/opt/"${APPLICATION}"_version.txt +msg_ok "Setup ${APPLICATION}" + +# Enable service +msg_info "Enabling Service" +systemctl enable -q --now speedtest_rs.service +msg_ok "Enabled Service" + +motd_ssh +customize + +# Cleanup +msg_info "Cleaning up" +rm -f "librespeed-rs-x86_64-unknown-linux-gnu.deb" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" \ No newline at end of file From df4926d1797e02541662eeab9060625452704abf Mon Sep 17 00:00:00 2001 From: Stroopwafe1 <48443491+Stroopwafe1@users.noreply.github.com> Date: Fri, 27 Jun 2025 12:09:44 +0200 Subject: [PATCH 003/463] Feat: Add script to install leantime --- ct/leantime.sh | 79 ++++++++++++++++++++ frontend/public/json/leantime.json | 35 +++++++++ install/leantime-install.sh | 113 +++++++++++++++++++++++++++++ 3 files changed, 227 insertions(+) create mode 100644 ct/leantime.sh create mode 100644 frontend/public/json/leantime.json create mode 100644 install/leantime-install.sh diff --git a/ct/leantime.sh b/ct/leantime.sh new file mode 100644 index 00000000..b084ef8a --- /dev/null +++ b/ct/leantime.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: Stroopwafe1 +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://leantime.io + +# App Default Values +# Name of the app (e.g. Google, Adventurelog, Apache-Guacamole" +APP="Leantime" +# Tags for Proxmox VE, maximum 2 pcs., no spaces allowed, separated by a semicolon ; (e.g. database | adblock;dhcp) +var_tags="${var_tags:-productivity}" +# Number of cores (1-X) (e.g. 4) - default are 2 +var_cpu="${var_cpu:-2}" +# Amount of used RAM in MB (e.g. 2048 or 4096) +var_ram="${var_ram:-2048}" +# Amount of used disk space in GB (e.g. 4 or 10) +var_disk="${var_disk:-20}" +# Default OS (e.g. debian, ubuntu, alpine) +var_os="${var_os:-debian}" +# Default OS version (e.g. 12 for debian, 24.04 for ubuntu, 3.20 for alpine) +var_version="${var_version:-12}" +# 1 = unprivileged container, 0 = privileged container +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + + # Check if installation is present | -f for file, -d for folder + if [[ ! -d /opt/${APP} ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + # Crawling the new version and checking whether an update is required + RELEASE=$(curl -fsSL https://api.github.com/repos/Leantime/leantime/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + # Creating Backup + msg_info "Creating Backup" + mariadb-dump leantime >"/opt/${APP}_db_backup_$(date +%F).sql" + tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" /opt/leantime + msg_ok "Backup Created" + + # Execute Update + msg_info "Updating $APP to v${RELEASE}" + curl -fsSL -o "${RELEASE}.tar.gz" "https://github.com/Leantime/leantime/archive/refs/tags/${RELEASE}.tar.gz" + tar xf "${RELEASE}.tar.gz" --strip-components=1 -C "/opt/${APP}" + msg_ok "Updated $APP to v${RELEASE}" + + # Cleaning up + msg_info "Cleaning Up" + rm -rf "${RELEASE}.tar.gz" + msg_ok "Cleanup Completed" + + # Last Action + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Update Successful" + else + msg_ok "No update required. ${APP} is already at v${RELEASE}" + 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}http://${IP}/install${CL}" diff --git a/frontend/public/json/leantime.json b/frontend/public/json/leantime.json new file mode 100644 index 00000000..b4594797 --- /dev/null +++ b/frontend/public/json/leantime.json @@ -0,0 +1,35 @@ +{ + "name": "Leantime", + "slug": "leantime", + "categories": [ + 12 + ], + "date_created": "2025-06-27", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 80, + "documentation": "https://docs.leantime.io/", + "config_path": "/opt/Leantime/config/.env", + "website": "https://leantime.io", + "logo": "https://assets.leantime.io/wp-content/uploads/2019/02/iconOnly-700.png", + "description": "Leantime is a goals focused project management system for non-project managers. Building with ADHD, Autism, and dyslexia in mind. ", + "install_methods": [ + { + "type": "default", + "script": "ct/leantime.sh", + "resources": { + "cpu": 2, + "ram": 2048, + "hdd": 20, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} diff --git a/install/leantime-install.sh b/install/leantime-install.sh new file mode 100644 index 00000000..c7d60c7c --- /dev/null +++ b/install/leantime-install.sh @@ -0,0 +1,113 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: Stroopwafe1 +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://leantime.io + +# Import Functions und Setup +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +PHP_VERSION=8.4 +PHP_MODULE=mysql +PHP_APACHE=YES +PHP_FPM=YES + +msg_info "Installing Apache2" +$STD apt-get install -y \ + apache2 +msg_ok "Installed Apache2" + +setup_php + +msg_info "Installing Apache2 mod for PHP" +$STD apt-get install -y \ + "libapache2-mod-php${PHP_VERSION}" +msg_ok "Installed Apache2 mod" + +setup_mariadb + +msg_ok "Installed Dependencies" + +# Template: MySQL Database +msg_info "Setting up Database" +systemctl enable -q --now mariadb +DB_NAME=leantime +DB_USER=leantime +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) +$STD mysql -u root -e "CREATE DATABASE $DB_NAME;" +$STD mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');" +$STD mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" +{ + echo "${APPLICATION} Credentials" + echo "Database User: $DB_USER" + echo "Database Password: $DB_PASS" + echo "Database Name: $DB_NAME" +} >>~/"$APPLICATION".creds +msg_ok "Set up Database" + +# Setup App +msg_info "Setup ${APPLICATION}" +APACHE_LOG_DIR=/var/log/apache2 +RELEASE=$(curl -fsSL https://api.github.com/repos/Leantime/leantime/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +curl -fsSL -o "${RELEASE}.tar.gz" "https://github.com/Leantime/leantime/releases/download/${RELEASE}/Leantime-${RELEASE}.tar.gz" +mkdir -p "/opt/${APPLICATION}" +mkdir -p /etc/apache2/sites-enabled +tar xf "${RELEASE}.tar.gz" --strip-components=1 -C "/opt/${APPLICATION}" +chown -R www-data:www-data "/opt/${APPLICATION}" +chmod -R 750 "/opt/${APPLICATION}" + +cat </etc/apache2/sites-enabled/000-default.conf + + ServerAdmin webmaster@localhost + DocumentRoot /opt/${APPLICATION}/public + DirectoryIndex index.php index.html index.cgi index.pl index.xhtml + Options +ExecCGI + + + Options FollowSymLinks + Require all granted + AllowOverride All + + + + Require all granted + + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + +EOF + +mv "/opt/${APPLICATION}/config/sample.env" "/opt/${APPLICATION}/config/.env" +sed -i -e "s|^LEAN_DB_DATABASE.*|LEAN_DB_DATABASE = '$DB_NAME'|" \ + -e "s|^LEAN_DB_USER.*|LEAN_DB_USER = '$DB_USER'|" \ + -e "s|^LEAN_DB_PASSWORD.*|LEAN_DB_PASSWORD = '$DB_PASS'|" \ + -e "s|^LEAN_SESSION_PASSWORD.*|LEAN_SESSION_PASSWORD = '$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)'|" \ + "/opt/${APPLICATION}/config/.env" + +a2enmod -q proxy_fcgi setenvif rewrite +a2enconf -q "php${PHP_VERSION}-fpm" + +sed -i -e "s/^;extension.\(curl\|fileinfo\|gd\|intl\|ldap\|mbstring\|exif\|mysqli\|odbc\|openssl\|pdo_mysql\)/extension=\1/g" "/etc/php/${PHP_VERSION}/apache2/php.ini" + +systemctl restart apache2 + +echo "${RELEASE}" >/opt/"${APPLICATION}"_version.txt +msg_ok "Setup ${APPLICATION}" + +motd_ssh +customize + +# Cleanup +msg_info "Cleaning up" +rm -f "${RELEASE}".tar.gz +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From da932c0473d2019d9bfb2c82dc7f39dbe064630a Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 27 Jun 2025 08:07:25 -0700 Subject: [PATCH 004/463] Convert deployment to use fetch_and_deploy_gh_release function. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com> --- ct/scraparr.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ct/scraparr.sh b/ct/scraparr.sh index 04ca13ef..d4004df3 100644 --- a/ct/scraparr.sh +++ b/ct/scraparr.sh @@ -35,10 +35,7 @@ function update_script() { msg_ok "Services Stopped" msg_info "Updating ${APP} to v${RELEASE}" - temp_file=$(mktemp) - curl -fsSL "https://github.com/thecfu/scraparr/archive/refs/tags/v2.2.2.tar.gz" -o "$temp_file" - tar -zxf "$temp_file" - mv "scrappar-${RELEASE}" /opt/scrappar + fetch_and_deploy_gh_release "scrappar" "thecfu/scraparr" pip -q install -r /opt/scrappar/src/scrappar/requirements.txt --root-user-action=ignore msg_ok "Updated ${APP}" From 6bb213e0d6bdfa2435b3fb5b1fc72c26943ff630 Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 27 Jun 2025 08:12:44 -0700 Subject: [PATCH 005/463] Convert deployment to use fetch_and_deploy_gh_release function. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com> --- install/scraparr-install.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/install/scraparr-install.sh b/install/scraparr-install.sh index 388ab78e..dcc777ce 100644 --- a/install/scraparr-install.sh +++ b/install/scraparr-install.sh @@ -21,12 +21,7 @@ $STD apt-get install -y \ msg_ok "Installed Dependencies" msg_info "Installing Scraparr" -temp_file=$(mktemp) -RELEASE=$(curl -fsSL https://api.github.com/repos/thecfu/scraparr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -echo "${RELEASE}" >"/opt/Scraparr_version.txt" -curl -fsSL "https://github.com/thecfu/scraparr/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file" -tar -zxf "$temp_file" -mv "scraparr-${RELEASE}" /opt/scraparr +fetch_and_deploy_gh_release "scrappar" "thecfu/scraparr" pip -q install -r /opt/scraparr/src/scraparr/requirements.txt --root-user-action=ignore chmod -R 755 /opt/scraparr mkdir /scraparr && mkdir /scraparr/config From 271e8638eb7e319aad846e31b24bc205c1572d04 Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 27 Jun 2025 08:14:06 -0700 Subject: [PATCH 006/463] Added documentation link to frontend json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added documentation link to frontend json Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com> --- frontend/public/json/scraparr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/public/json/scraparr.json b/frontend/public/json/scraparr.json index 4502bf2a..0711da04 100644 --- a/frontend/public/json/scraparr.json +++ b/frontend/public/json/scraparr.json @@ -9,7 +9,7 @@ "updateable": true, "privileged": false, "interface_port": 8989, - "documentation": null, + "documentation": "https://github.com/thecfu/scraparr/blob/main/README.md", "website": "https://github.com/thecfu/scraparr", "logo": "https://github.com/thecfu/scraparr/raw/main/.github/assets/logos/scraparr_logo.svg", "config_path": "/scraparr/config/config.yaml", From 66b4ff5ccb79c371407ca23bfa68ddab23fc0e02 Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 27 Jun 2025 08:16:52 -0700 Subject: [PATCH 007/463] Updated frontend json interface port --- frontend/public/json/scraparr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/public/json/scraparr.json b/frontend/public/json/scraparr.json index 0711da04..690e1919 100644 --- a/frontend/public/json/scraparr.json +++ b/frontend/public/json/scraparr.json @@ -8,7 +8,7 @@ "type": "ct", "updateable": true, "privileged": false, - "interface_port": 8989, + "interface_port": 7100, "documentation": "https://github.com/thecfu/scraparr/blob/main/README.md", "website": "https://github.com/thecfu/scraparr", "logo": "https://github.com/thecfu/scraparr/raw/main/.github/assets/logos/scraparr_logo.svg", From ea1cbfe2079fc07f4ccb6ae4d15a3c020e4a8e0b Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 27 Jun 2025 08:54:16 -0700 Subject: [PATCH 008/463] uvenv mgiration --- ct/scraparr.sh | 33 ++++- install/scraparr-install.sh | 23 ++- misc/build.func | 22 +-- misc/install.func | 276 ++++++++++++++++++------------------ 4 files changed, 184 insertions(+), 170 deletions(-) diff --git a/ct/scraparr.sh b/ct/scraparr.sh index d4004df3..34d40cca 100644 --- a/ct/scraparr.sh +++ b/ct/scraparr.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +source <(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/build.func) # Copyright (c) 2021-2025 community-scripts ORG # Author: JasonGreenC # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE @@ -27,12 +27,34 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi - msg_info "Updating ${APP}" + + msg_info "Stopping Services" + systemctl stop scraparr + msg_ok "Services Stopped" + + export SCRAPARR_VENV_PATH="/opt/scraparr/.venv" + export SCRAPARR_EXPORTER_BIN="${SCRAPARR_VENV_PATH}/bin/scraparr" + + if [[ ! -d "$PVE_VENV_PATH" || ! -x "$PVE_EXPORTER_BIN" ]]; then + PYTHON_VERSION="3.12" setup_uv + msg_info "Migrating to uv/venv" + rm -rf "$PVE_VENV_PATH" + mkdir -p /opt/scraparr + cd /opt/scraparr + $STD uv venv "$PVE_VENV_PATH" + $STD "$PVE_VENV_PATH/bin/python" -m ensurepip --upgrade + $STD "$PVE_VENV_PATH/bin/python" -m pip install --upgrade pip + $STD "$PVE_VENV_PATH/bin/python" -m pip install prometheus-pve-exporter + msg_ok "Migrated to uv/venv" + else + msg_info "Updating Prometheus Proxmox VE Exporter" + PYTHON_VERSION="3.12" setup_uv + $STD "$PVE_VENV_PATH/bin/python" -m pip install --upgrade prometheus-pve-exporter + msg_ok "Updated Prometheus Proxmox VE Exporter" + fi RELEASE=$(curl -fsSL https://api.github.com/repos/thecfu/scraparr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then - msg_info "Stopping Services" - systemctl stop scraparr - msg_ok "Services Stopped" + msg_info "Updating ${APP} to v${RELEASE}" fetch_and_deploy_gh_release "scrappar" "thecfu/scraparr" @@ -52,7 +74,6 @@ 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}:7100${CL}" diff --git a/install/scraparr-install.sh b/install/scraparr-install.sh index dcc777ce..65eb49ae 100644 --- a/install/scraparr-install.sh +++ b/install/scraparr-install.sh @@ -13,18 +13,17 @@ setting_up_container network_check update_os -msg_info "Installing Dependencies" -$STD apt-get install -y \ - python3 \ - python3-pip - -msg_ok "Installed Dependencies" +PYTHON_VERSION="3.12" setup_uv msg_info "Installing Scraparr" fetch_and_deploy_gh_release "scrappar" "thecfu/scraparr" -pip -q install -r /opt/scraparr/src/scraparr/requirements.txt --root-user-action=ignore +cd /opt/scraparr +$STD uv venv /opt/scraparr/.venv +$STD /opt/scraparr/.venv/bin/python -m ensurepip --upgrade +$STD /opt/scraparr/.venv/bin/python -m pip install --upgrade pip +$STD /opt/scraparr/.venv/bin/python -m pip install -r /opt/scraparr/src/scraparr/requirements.txt chmod -R 755 /opt/scraparr -mkdir /scraparr && mkdir /scraparr/config +mkdir -p /scraparr/config mv /opt/scraparr/config.yaml /scraparr/config/config.yaml chmod -R 755 /scraparr msg_ok "Installed Scraparr" @@ -35,29 +34,23 @@ cat </etc/systemd/system/scraparr.service Description=Scraparr Wants=network-online.target After=network.target - [Service] Type=simple -ExecStart=/usr/bin/python3 -m scraparr.scraparr -WorkingDirectory=/opt/scraparr/src +ExecStart=/opt/scraparr/.venv/bin/python -m /opt/scraparr/src/scraparr/scraparr User=root Restart=always - [Install] WantedBy=multi-user.target EOF - systemctl daemon-reload systemctl enable -q --now scraparr - msg_ok "Configured Service" motd_ssh customize msg_info "Cleaning up" -rm -f "$temp_file" $STD apt-get -y autoremove $STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/misc/build.func b/misc/build.func index b75e5b38..dabc7265 100644 --- a/misc/build.func +++ b/misc/build.func @@ -15,14 +15,14 @@ variables() { CT_TYPE=${var_unprivileged:-$CT_TYPE} } -source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) +source <(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/api.func) if command -v curl >/dev/null 2>&1; then - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/core.func) load_functions #echo "(build.func) Loaded core.func via curl" elif command -v wget >/dev/null 2>&1; then - source <(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) + source <(wget -qO- https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/core.func) load_functions #echo "(build.func) Loaded core.func via wget" fi @@ -35,7 +35,7 @@ catch_errors() { # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { - source /dev/stdin <<<$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) + source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/api.func) printf "\e[?25h" local exit_code="$?" local line_number="$1" @@ -1017,7 +1017,7 @@ install_script() { header_info echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" METHOD="advanced" - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/config-file.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/config-file.func) config_file break ;; @@ -1093,7 +1093,7 @@ check_container_storage() { } start() { - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/tools.func) if command -v pveversion >/dev/null 2>&1; then install_script else @@ -1155,9 +1155,9 @@ build_container() { TEMP_DIR=$(mktemp -d) pushd "$TEMP_DIR" >/dev/null if [ "$var_os" == "alpine" ]; then - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)" + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/alpine-install.func)" else - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)" + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/install.func)" fi export DIAGNOSTICS="$DIAGNOSTICS" export RANDOM_UUID="$RANDOM_UUID" @@ -1192,7 +1192,7 @@ build_container() { $PW " # This executes create_lxc.sh and creates the container and .conf file - CREATE_CMD="bash -c \"\$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)\"" + CREATE_CMD="bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/create_lxc.sh)\"" eval "$CREATE_CMD" RET=$? if [[ $RET -ne 0 ]]; then @@ -1282,7 +1282,7 @@ EOF' pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" fi msg_ok "Customized LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/install/$var_install.sh)" $? + lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/install/$var_install.sh)" $? } @@ -1295,7 +1295,7 @@ description() { cat < - Logo + Logo

${APP} LXC

diff --git a/misc/install.func b/misc/install.func index efc77be5..45f0c13e 100644 --- a/misc/install.func +++ b/misc/install.func @@ -6,134 +6,134 @@ # https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE if ! command -v curl >/dev/null 2>&1; then - printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 - apt-get update >/dev/null 2>&1 - apt-get install -y curl >/dev/null 2>&1 + printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 + apt-get update >/dev/null 2>&1 + apt-get install -y curl >/dev/null 2>&1 fi -source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) +source <(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/core.func) load_functions # This function enables IPv6 if it's not disabled and sets verbose mode verb_ip6() { - set_std_mode # Set STD mode based on VERBOSE + set_std_mode # Set STD mode based on VERBOSE - if [ "$DISABLEIPV6" == "yes" ]; then - echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf - $STD sysctl -p - fi + if [ "$DISABLEIPV6" == "yes" ]; then + echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf + $STD sysctl -p + fi } # This function sets error handling options and defines the error_handler function to handle errors catch_errors() { - set -Eeuo pipefail - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + set -Eeuo pipefail + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } # This function handles errors error_handler() { - source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) - printf "\e[?25h" - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message" + source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) + printf "\e[?25h" + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message" - if [[ "$line_number" -eq 50 ]]; then - echo -e "The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\n" - post_update_to_api "failed" "No error message, script ran in silent mode" - else - post_update_to_api "failed" "${command}" - fi + if [[ "$line_number" -eq 50 ]]; then + echo -e "The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\n" + post_update_to_api "failed" "No error message, script ran in silent mode" + else + post_update_to_api "failed" "${command}" + fi } # This function sets up the Container OS by generating the locale, setting the timezone, and checking the network connection setting_up_container() { - msg_info "Setting up Container OS" - for ((i = RETRY_NUM; i > 0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break + msg_info "Setting up Container OS" + for ((i = RETRY_NUM; i > 0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + done + if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e "${NETWORK}Check Network Settings" + exit 1 fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - done - if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e "${NETWORK}Check Network Settings" - exit 1 - fi - rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED - systemctl disable -q --now systemd-networkd-wait-online.service - msg_ok "Set up Container OS" - msg_custom "${CM}" "${GN}" "Network Connected: ${BL}$(hostname -I)" + rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + systemctl disable -q --now systemd-networkd-wait-online.service + msg_ok "Set up Container OS" + msg_custom "${CM}" "${GN}" "Network Connected: ${BL}$(hostname -I)" } # This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected network_check() { - set +e - trap - ERR - ipv4_connected=false - ipv6_connected=false - sleep 1 + set +e + trap - ERR + ipv4_connected=false + ipv6_connected=false + sleep 1 - # Check IPv4 connectivity to Google, Cloudflare & Quad9 DNS servers. - if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then - msg_ok "IPv4 Internet Connected" - ipv4_connected=true - else - msg_error "IPv4 Internet Not Connected" - fi - - # Check IPv6 connectivity to Google, Cloudflare & Quad9 DNS servers. - if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null || ping6 -c 1 -W 1 2001:4860:4860::8888 &>/dev/null || ping6 -c 1 -W 1 2620:fe::fe &>/dev/null; then - msg_ok "IPv6 Internet Connected" - ipv6_connected=true - else - msg_error "IPv6 Internet Not Connected" - fi - - # If both IPv4 and IPv6 checks fail, prompt the user - if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then - read -r -p "No Internet detected, would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e "${INFO}${RD}Expect Issues Without Internet${CL}" + # Check IPv4 connectivity to Google, Cloudflare & Quad9 DNS servers. + if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then + msg_ok "IPv4 Internet Connected" + ipv4_connected=true else - echo -e "${NETWORK}Check Network Settings" - exit 1 + msg_error "IPv4 Internet Not Connected" fi - fi - # DNS resolution checks for GitHub-related domains (IPv4 and/or IPv6) - GITHUB_HOSTS=("github.com" "raw.githubusercontent.com" "api.github.com" "git.community-scripts.org") - GITHUB_STATUS="GitHub DNS:" - DNS_FAILED=false - - for HOST in "${GITHUB_HOSTS[@]}"; do - RESOLVEDIP=$(getent hosts "$HOST" | awk '{ print $1 }' | grep -E '(^([0-9]{1,3}\.){3}[0-9]{1,3}$)|(^[a-fA-F0-9:]+$)' | head -n1) - if [[ -z "$RESOLVEDIP" ]]; then - GITHUB_STATUS+="$HOST:($DNSFAIL)" - DNS_FAILED=true + # Check IPv6 connectivity to Google, Cloudflare & Quad9 DNS servers. + if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null || ping6 -c 1 -W 1 2001:4860:4860::8888 &>/dev/null || ping6 -c 1 -W 1 2620:fe::fe &>/dev/null; then + msg_ok "IPv6 Internet Connected" + ipv6_connected=true else - GITHUB_STATUS+=" $HOST:($DNSOK)" + msg_error "IPv6 Internet Not Connected" fi - done - if [[ "$DNS_FAILED" == true ]]; then - fatal "$GITHUB_STATUS" - else - msg_ok "$GITHUB_STATUS" - fi + # If both IPv4 and IPv6 checks fail, prompt the user + if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then + read -r -p "No Internet detected, would you like to continue anyway? " prompt + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + echo -e "${INFO}${RD}Expect Issues Without Internet${CL}" + else + echo -e "${NETWORK}Check Network Settings" + exit 1 + fi + fi - set -e - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + # DNS resolution checks for GitHub-related domains (IPv4 and/or IPv6) + GITHUB_HOSTS=("github.com" "raw.githubusercontent.com" "api.github.com" "git.community-scripts.org") + GITHUB_STATUS="GitHub DNS:" + DNS_FAILED=false + + for HOST in "${GITHUB_HOSTS[@]}"; do + RESOLVEDIP=$(getent hosts "$HOST" | awk '{ print $1 }' | grep -E '(^([0-9]{1,3}\.){3}[0-9]{1,3}$)|(^[a-fA-F0-9:]+$)' | head -n1) + if [[ -z "$RESOLVEDIP" ]]; then + GITHUB_STATUS+="$HOST:($DNSFAIL)" + DNS_FAILED=true + else + GITHUB_STATUS+=" $HOST:($DNSOK)" + fi + done + + if [[ "$DNS_FAILED" == true ]]; then + fatal "$GITHUB_STATUS" + else + msg_ok "$GITHUB_STATUS" + fi + + set -e + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } # This function updates the Container OS by running apt-get update and upgrade update_os() { - msg_info "Updating Container OS" - if [[ "$CACHER" == "yes" ]]; then - echo "Acquire::http::Proxy-Auto-Detect \"/usr/local/bin/apt-proxy-detect.sh\";" >/etc/apt/apt.conf.d/00aptproxy - cat </usr/local/bin/apt-proxy-detect.sh + msg_info "Updating Container OS" + if [[ "$CACHER" == "yes" ]]; then + echo "Acquire::http::Proxy-Auto-Detect \"/usr/local/bin/apt-proxy-detect.sh\";" >/etc/apt/apt.conf.d/00aptproxy + cat </usr/local/bin/apt-proxy-detect.sh #!/bin/bash if nc -w1 -z "${CACHER_IP}" 3142; then echo -n "http://${CACHER_IP}:3142" @@ -141,66 +141,66 @@ else echo -n "DIRECT" fi EOF - chmod +x /usr/local/bin/apt-proxy-detect.sh - fi - $STD apt-get update - $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade - rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED - msg_ok "Updated Container OS" - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) + chmod +x /usr/local/bin/apt-proxy-detect.sh + fi + $STD apt-get update + $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade + rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + msg_ok "Updated Container OS" + source <(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/tools.func) } # This function modifies the message of the day (motd) and SSH settings motd_ssh() { - grep -qxF "export TERM='xterm-256color'" /root/.bashrc || echo "export TERM='xterm-256color'" >>/root/.bashrc + grep -qxF "export TERM='xterm-256color'" /root/.bashrc || echo "export TERM='xterm-256color'" >>/root/.bashrc - if [ -f "/etc/os-release" ]; then - OS_NAME=$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '"') - OS_VERSION=$(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"') - elif [ -f "/etc/debian_version" ]; then - OS_NAME="Debian" - OS_VERSION=$(cat /etc/debian_version) - fi + if [ -f "/etc/os-release" ]; then + OS_NAME=$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '"') + OS_VERSION=$(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"') + elif [ -f "/etc/debian_version" ]; then + OS_NAME="Debian" + OS_VERSION=$(cat /etc/debian_version) + fi - PROFILE_FILE="/etc/profile.d/00_lxc-details.sh" - echo "echo -e \"\"" >"$PROFILE_FILE" - echo -e "echo -e \"${BOLD}${YW}${APPLICATION} LXC Container - DEV Repository${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${RD}WARNING: This is a DEVELOPMENT version (ProxmoxVED). Do NOT use in production!${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} IP Address: ${GN}\$(hostname -I | awk '{print \$1}')${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} Repository: ${GN}https://github.com/community-scripts/ProxmoxVED${CL}\"" >>"$PROFILE_FILE" - echo "echo \"\"" >>"$PROFILE_FILE" + PROFILE_FILE="/etc/profile.d/00_lxc-details.sh" + echo "echo -e \"\"" >"$PROFILE_FILE" + echo -e "echo -e \"${BOLD}${YW}${APPLICATION} LXC Container - DEV Repository${CL}\"" >>"$PROFILE_FILE" + echo -e "echo -e \"${RD}WARNING: This is a DEVELOPMENT version (ProxmoxVED). Do NOT use in production!${CL}\"" >>"$PROFILE_FILE" + echo -e "echo -e \"${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}\"" >>"$PROFILE_FILE" + echo -e "echo -e \"${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE" + echo -e "echo -e \"${YW} IP Address: ${GN}\$(hostname -I | awk '{print \$1}')${CL}\"" >>"$PROFILE_FILE" + echo -e "echo -e \"${YW} Repository: ${GN}https://github.com/community-scripts/ProxmoxVED${CL}\"" >>"$PROFILE_FILE" + echo "echo \"\"" >>"$PROFILE_FILE" - chmod -x /etc/update-motd.d/* + chmod -x /etc/update-motd.d/* - if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd - fi + if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd + fi } # This function customizes the container by modifying the getty service and enabling auto-login for the root user customize() { - if [[ "$PASSWORD" == "" ]]; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE + if [[ "$PASSWORD" == "" ]]; then + msg_info "Customizing Container" + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" - fi - echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update - chmod +x /usr/bin/update - if [[ -n "${SSH_AUTHORIZED_KEY}" ]]; then - mkdir -p /root/.ssh - echo "${SSH_AUTHORIZED_KEY}" >/root/.ssh/authorized_keys - chmod 700 /root/.ssh - chmod 600 /root/.ssh/authorized_keys - fi + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" + fi + echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update + chmod +x /usr/bin/update + if [[ -n "${SSH_AUTHORIZED_KEY}" ]]; then + mkdir -p /root/.ssh + echo "${SSH_AUTHORIZED_KEY}" >/root/.ssh/authorized_keys + chmod 700 /root/.ssh + chmod 600 /root/.ssh/authorized_keys + fi } From 39eef6eb4998ed8e949dd5f06d0fd9df9d398cdf Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 27 Jun 2025 09:01:55 -0700 Subject: [PATCH 009/463] fixed build links for dev --- ct/scraparr.sh | 95 +++++++++++++++++++++++------------------------ misc/build.func | 22 +++++------ misc/install.func | 4 +- 3 files changed, 60 insertions(+), 61 deletions(-) diff --git a/ct/scraparr.sh b/ct/scraparr.sh index 34d40cca..eac70960 100644 --- a/ct/scraparr.sh +++ b/ct/scraparr.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/build.func) +source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/build.func) # Copyright (c) 2021-2025 community-scripts ORG # Author: JasonGreenC # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE @@ -20,54 +20,53 @@ color catch_errors function update_script() { - header_info - check_container_storage - check_container_resources - if [[ ! -d /opt/scraparr/ ]]; then - msg_error "No ${APP} Installation Found!" + header_info + check_container_storage + check_container_resources + if [[ ! -d /opt/scraparr/ ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + msg_info "Stopping Services" + systemctl stop scraparr + msg_ok "Services Stopped" + + export SCRAPARR_VENV_PATH="/opt/scraparr/.venv" + export SCRAPARR_EXPORTER_BIN="${SCRAPARR_VENV_PATH}/bin/scraparr" + + if [[ ! -d "$PVE_VENV_PATH" || ! -x "$PVE_EXPORTER_BIN" ]]; then + PYTHON_VERSION="3.12" setup_uv + msg_info "Migrating to uv/venv" + rm -rf "$PVE_VENV_PATH" + mkdir -p /opt/scraparr + cd /opt/scraparr + $STD uv venv "$PVE_VENV_PATH" + $STD "$PVE_VENV_PATH/bin/python" -m ensurepip --upgrade + $STD "$PVE_VENV_PATH/bin/python" -m pip install --upgrade pip + $STD "$PVE_VENV_PATH/bin/python" -m pip install prometheus-pve-exporter + msg_ok "Migrated to uv/venv" + else + msg_info "Updating Prometheus Proxmox VE Exporter" + PYTHON_VERSION="3.12" setup_uv + $STD "$PVE_VENV_PATH/bin/python" -m pip install --upgrade prometheus-pve-exporter + msg_ok "Updated Prometheus Proxmox VE Exporter" + fi + RELEASE=$(curl -fsSL https://api.github.com/repos/thecfu/scraparr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + + msg_info "Updating ${APP} to v${RELEASE}" + fetch_and_deploy_gh_release "scrappar" "thecfu/scraparr" + pip -q install -r /opt/scrappar/src/scrappar/requirements.txt --root-user-action=ignore + msg_ok "Updated ${APP}" + + msg_info "Starting Service" + systemctl start scraparr + msg_ok "Started Service" + else + msg_ok "No update required. ${APP} is already at v${RELEASE}" + fi exit - fi - - msg_info "Stopping Services" - systemctl stop scraparr - msg_ok "Services Stopped" - - export SCRAPARR_VENV_PATH="/opt/scraparr/.venv" - export SCRAPARR_EXPORTER_BIN="${SCRAPARR_VENV_PATH}/bin/scraparr" - - if [[ ! -d "$PVE_VENV_PATH" || ! -x "$PVE_EXPORTER_BIN" ]]; then - PYTHON_VERSION="3.12" setup_uv - msg_info "Migrating to uv/venv" - rm -rf "$PVE_VENV_PATH" - mkdir -p /opt/scraparr - cd /opt/scraparr - $STD uv venv "$PVE_VENV_PATH" - $STD "$PVE_VENV_PATH/bin/python" -m ensurepip --upgrade - $STD "$PVE_VENV_PATH/bin/python" -m pip install --upgrade pip - $STD "$PVE_VENV_PATH/bin/python" -m pip install prometheus-pve-exporter - msg_ok "Migrated to uv/venv" - else - msg_info "Updating Prometheus Proxmox VE Exporter" - PYTHON_VERSION="3.12" setup_uv - $STD "$PVE_VENV_PATH/bin/python" -m pip install --upgrade prometheus-pve-exporter - msg_ok "Updated Prometheus Proxmox VE Exporter" - fi - RELEASE=$(curl -fsSL https://api.github.com/repos/thecfu/scraparr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') - if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then - - - msg_info "Updating ${APP} to v${RELEASE}" - fetch_and_deploy_gh_release "scrappar" "thecfu/scraparr" - pip -q install -r /opt/scrappar/src/scrappar/requirements.txt --root-user-action=ignore - msg_ok "Updated ${APP}" - - msg_info "Starting Service" - systemctl start scraparr - msg_ok "Started Service" - else - msg_ok "No update required. ${APP} is already at v${RELEASE}" - fi - exit } start diff --git a/misc/build.func b/misc/build.func index dabc7265..e7003e96 100644 --- a/misc/build.func +++ b/misc/build.func @@ -15,14 +15,14 @@ variables() { CT_TYPE=${var_unprivileged:-$CT_TYPE} } -source <(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/api.func) +source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/api.func) if command -v curl >/dev/null 2>&1; then - source <(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/core.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/core.func) load_functions #echo "(build.func) Loaded core.func via curl" elif command -v wget >/dev/null 2>&1; then - source <(wget -qO- https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/core.func) + source <(wget -qO- https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/core.func) load_functions #echo "(build.func) Loaded core.func via wget" fi @@ -35,7 +35,7 @@ catch_errors() { # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { - source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/api.func) + source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/api.func) printf "\e[?25h" local exit_code="$?" local line_number="$1" @@ -1017,7 +1017,7 @@ install_script() { header_info echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" METHOD="advanced" - source <(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/config-file.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/config-file.func) config_file break ;; @@ -1093,7 +1093,7 @@ check_container_storage() { } start() { - source <(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/tools.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/tools.func) if command -v pveversion >/dev/null 2>&1; then install_script else @@ -1155,9 +1155,9 @@ build_container() { TEMP_DIR=$(mktemp -d) pushd "$TEMP_DIR" >/dev/null if [ "$var_os" == "alpine" ]; then - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/alpine-install.func)" + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/alpine-install.func)" else - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/install.func)" + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/install.func)" fi export DIAGNOSTICS="$DIAGNOSTICS" export RANDOM_UUID="$RANDOM_UUID" @@ -1192,7 +1192,7 @@ build_container() { $PW " # This executes create_lxc.sh and creates the container and .conf file - CREATE_CMD="bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/create_lxc.sh)\"" + CREATE_CMD="bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/create_lxc.sh)\"" eval "$CREATE_CMD" RET=$? if [[ $RET -ne 0 ]]; then @@ -1282,7 +1282,7 @@ EOF' pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" fi msg_ok "Customized LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/install/$var_install.sh)" $? + lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/install/$var_install.sh)" $? } @@ -1295,7 +1295,7 @@ description() { cat < - Logo + Logo

${APP} LXC

diff --git a/misc/install.func b/misc/install.func index 45f0c13e..255e82c9 100644 --- a/misc/install.func +++ b/misc/install.func @@ -10,7 +10,7 @@ if ! command -v curl >/dev/null 2>&1; then apt-get update >/dev/null 2>&1 apt-get install -y curl >/dev/null 2>&1 fi -source <(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/core.func) +source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/core.func) load_functions # This function enables IPv6 if it's not disabled and sets verbose mode @@ -147,7 +147,7 @@ EOF $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Container OS" - source <(curl -fsSL https://raw.githubusercontent.com/JasonGReenc/ProxmoxVED/refs/head/scraparr/misc/tools.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/tools.func) } # This function modifies the message of the day (motd) and SSH settings From 16bea4814848dbad28cbc4c41ae9cac4436a6db4 Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 27 Jun 2025 09:04:12 -0700 Subject: [PATCH 010/463] fixed build links for dev --- ct/scraparr.sh | 2 +- misc/build.func | 22 +++++++++++----------- misc/install.func | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/ct/scraparr.sh b/ct/scraparr.sh index eac70960..3908a853 100644 --- a/ct/scraparr.sh +++ b/ct/scraparr.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/build.func) +source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/build.func) # Copyright (c) 2021-2025 community-scripts ORG # Author: JasonGreenC # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE diff --git a/misc/build.func b/misc/build.func index e7003e96..48146d9d 100644 --- a/misc/build.func +++ b/misc/build.func @@ -15,14 +15,14 @@ variables() { CT_TYPE=${var_unprivileged:-$CT_TYPE} } -source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/api.func) +source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/api.func) if command -v curl >/dev/null 2>&1; then - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/core.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/core.func) load_functions #echo "(build.func) Loaded core.func via curl" elif command -v wget >/dev/null 2>&1; then - source <(wget -qO- https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/core.func) + source <(wget -qO- https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/core.func) load_functions #echo "(build.func) Loaded core.func via wget" fi @@ -35,7 +35,7 @@ catch_errors() { # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { - source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/api.func) + source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/api.func) printf "\e[?25h" local exit_code="$?" local line_number="$1" @@ -1017,7 +1017,7 @@ install_script() { header_info echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" METHOD="advanced" - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/config-file.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/config-file.func) config_file break ;; @@ -1093,7 +1093,7 @@ check_container_storage() { } start() { - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/tools.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/tools.func) if command -v pveversion >/dev/null 2>&1; then install_script else @@ -1155,9 +1155,9 @@ build_container() { TEMP_DIR=$(mktemp -d) pushd "$TEMP_DIR" >/dev/null if [ "$var_os" == "alpine" ]; then - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/alpine-install.func)" + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/alpine-install.func)" else - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/install.func)" + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/install.func)" fi export DIAGNOSTICS="$DIAGNOSTICS" export RANDOM_UUID="$RANDOM_UUID" @@ -1192,7 +1192,7 @@ build_container() { $PW " # This executes create_lxc.sh and creates the container and .conf file - CREATE_CMD="bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/create_lxc.sh)\"" + CREATE_CMD="bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/create_lxc.sh)\"" eval "$CREATE_CMD" RET=$? if [[ $RET -ne 0 ]]; then @@ -1282,7 +1282,7 @@ EOF' pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" fi msg_ok "Customized LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/install/$var_install.sh)" $? + lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/install/$var_install.sh)" $? } @@ -1295,7 +1295,7 @@ description() { cat < - Logo + Logo

${APP} LXC

diff --git a/misc/install.func b/misc/install.func index 255e82c9..9f23efd8 100644 --- a/misc/install.func +++ b/misc/install.func @@ -10,7 +10,7 @@ if ! command -v curl >/dev/null 2>&1; then apt-get update >/dev/null 2>&1 apt-get install -y curl >/dev/null 2>&1 fi -source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/core.func) +source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/core.func) load_functions # This function enables IPv6 if it's not disabled and sets verbose mode @@ -147,7 +147,7 @@ EOF $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Container OS" - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr/misc/tools.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/tools.func) } # This function modifies the message of the day (motd) and SSH settings From 57327ec6125b09b742f06356299ed7effeb1cb2a Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 27 Jun 2025 09:05:47 -0700 Subject: [PATCH 011/463] fixed build links for dev --- ct/scraparr.sh | 2 +- misc/build.func | 22 +++++++++++----------- misc/install.func | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ct/scraparr.sh b/ct/scraparr.sh index 3908a853..5fc2199c 100644 --- a/ct/scraparr.sh +++ b/ct/scraparr.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/build.func) +source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/build.func) # Copyright (c) 2021-2025 community-scripts ORG # Author: JasonGreenC # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE diff --git a/misc/build.func b/misc/build.func index 48146d9d..91bf98e0 100644 --- a/misc/build.func +++ b/misc/build.func @@ -15,14 +15,14 @@ variables() { CT_TYPE=${var_unprivileged:-$CT_TYPE} } -source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/api.func) +source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/api.func) if command -v curl >/dev/null 2>&1; then - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/core.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/core.func) load_functions #echo "(build.func) Loaded core.func via curl" elif command -v wget >/dev/null 2>&1; then - source <(wget -qO- https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/core.func) + source <(wget -qO- https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/core.func) load_functions #echo "(build.func) Loaded core.func via wget" fi @@ -35,7 +35,7 @@ catch_errors() { # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { - source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/api.func) + source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/api.func) printf "\e[?25h" local exit_code="$?" local line_number="$1" @@ -1017,7 +1017,7 @@ install_script() { header_info echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" METHOD="advanced" - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/config-file.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/config-file.func) config_file break ;; @@ -1093,7 +1093,7 @@ check_container_storage() { } start() { - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/tools.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/tools.func) if command -v pveversion >/dev/null 2>&1; then install_script else @@ -1155,9 +1155,9 @@ build_container() { TEMP_DIR=$(mktemp -d) pushd "$TEMP_DIR" >/dev/null if [ "$var_os" == "alpine" ]; then - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/alpine-install.func)" + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/alpine-install.func)" else - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/install.func)" + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/install.func)" fi export DIAGNOSTICS="$DIAGNOSTICS" export RANDOM_UUID="$RANDOM_UUID" @@ -1192,7 +1192,7 @@ build_container() { $PW " # This executes create_lxc.sh and creates the container and .conf file - CREATE_CMD="bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/create_lxc.sh)\"" + CREATE_CMD="bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/create_lxc.sh)\"" eval "$CREATE_CMD" RET=$? if [[ $RET -ne 0 ]]; then @@ -1282,7 +1282,7 @@ EOF' pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" fi msg_ok "Customized LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/install/$var_install.sh)" $? + lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/install/$var_install.sh)" $? } @@ -1295,7 +1295,7 @@ description() { cat < - Logo + Logo

${APP} LXC

diff --git a/misc/install.func b/misc/install.func index 9f23efd8..94ddff89 100644 --- a/misc/install.func +++ b/misc/install.func @@ -10,7 +10,7 @@ if ! command -v curl >/dev/null 2>&1; then apt-get update >/dev/null 2>&1 apt-get install -y curl >/dev/null 2>&1 fi -source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/core.func) +source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/core.func) load_functions # This function enables IPv6 if it's not disabled and sets verbose mode From 9f01464234db7db6123202b4d6bdbd72be6b9c24 Mon Sep 17 00:00:00 2001 From: Stroopwafe1 <48443491+Stroopwafe1@users.noreply.github.com> Date: Fri, 27 Jun 2025 18:25:15 +0200 Subject: [PATCH 012/463] Chore: Implement feedback --- ct/leantime.sh | 42 +++++------------------------- frontend/public/json/leantime.json | 2 +- install/leantime-install.sh | 10 +------ 3 files changed, 8 insertions(+), 46 deletions(-) diff --git a/ct/leantime.sh b/ct/leantime.sh index b084ef8a..cc58a765 100644 --- a/ct/leantime.sh +++ b/ct/leantime.sh @@ -1,27 +1,18 @@ #!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) # Copyright (c) 2021-2025 community-scripts ORG # Author: Stroopwafe1 # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://leantime.io -# App Default Values -# Name of the app (e.g. Google, Adventurelog, Apache-Guacamole" APP="Leantime" -# Tags for Proxmox VE, maximum 2 pcs., no spaces allowed, separated by a semicolon ; (e.g. database | adblock;dhcp) var_tags="${var_tags:-productivity}" -# Number of cores (1-X) (e.g. 4) - default are 2 var_cpu="${var_cpu:-2}" -# Amount of used RAM in MB (e.g. 2048 or 4096) var_ram="${var_ram:-2048}" -# Amount of used disk space in GB (e.g. 4 or 10) var_disk="${var_disk:-20}" -# Default OS (e.g. debian, ubuntu, alpine) var_os="${var_os:-debian}" -# Default OS version (e.g. 12 for debian, 24.04 for ubuntu, 3.20 for alpine) var_version="${var_version:-12}" -# 1 = unprivileged container, 0 = privileged container var_unprivileged="${var_unprivileged:-1}" header_info "$APP" @@ -40,32 +31,11 @@ function update_script() { exit fi - # Crawling the new version and checking whether an update is required - RELEASE=$(curl -fsSL https://api.github.com/repos/Leantime/leantime/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then - # Creating Backup - msg_info "Creating Backup" - mariadb-dump leantime >"/opt/${APP}_db_backup_$(date +%F).sql" - tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" /opt/leantime - msg_ok "Backup Created" - - # Execute Update - msg_info "Updating $APP to v${RELEASE}" - curl -fsSL -o "${RELEASE}.tar.gz" "https://github.com/Leantime/leantime/archive/refs/tags/${RELEASE}.tar.gz" - tar xf "${RELEASE}.tar.gz" --strip-components=1 -C "/opt/${APP}" - msg_ok "Updated $APP to v${RELEASE}" - - # Cleaning up - msg_info "Cleaning Up" - rm -rf "${RELEASE}.tar.gz" - msg_ok "Cleanup Completed" - - # Last Action - echo "${RELEASE}" >/opt/${APP}_version.txt - msg_ok "Update Successful" - else - msg_ok "No update required. ${APP} is already at v${RELEASE}" - fi + msg_info "Creating Backup" + mariadb-dump leantime >"/opt/${APP}_db_backup_$(date +%F).sql" + tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" "/opt/${APP}" + msg_ok "Backup Created" + fetch_and_deploy_gh_release "$APP" "Leantime/leantime" "prebuild" "latest" "/opt/${APP}" Leantime-v[0-9].[0-9].[0-9].tar.gz exit } diff --git a/frontend/public/json/leantime.json b/frontend/public/json/leantime.json index b4594797..e5e0fec8 100644 --- a/frontend/public/json/leantime.json +++ b/frontend/public/json/leantime.json @@ -12,7 +12,7 @@ "documentation": "https://docs.leantime.io/", "config_path": "/opt/Leantime/config/.env", "website": "https://leantime.io", - "logo": "https://assets.leantime.io/wp-content/uploads/2019/02/iconOnly-700.png", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/leantime.webp", "description": "Leantime is a goals focused project management system for non-project managers. Building with ADHD, Autism, and dyslexia in mind. ", "install_methods": [ { diff --git a/install/leantime-install.sh b/install/leantime-install.sh index c7d60c7c..475a464a 100644 --- a/install/leantime-install.sh +++ b/install/leantime-install.sh @@ -5,7 +5,6 @@ # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://leantime.io -# Import Functions und Setup source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color verb_ip6 @@ -35,7 +34,6 @@ setup_mariadb msg_ok "Installed Dependencies" -# Template: MySQL Database msg_info "Setting up Database" systemctl enable -q --now mariadb DB_NAME=leantime @@ -55,11 +53,7 @@ msg_ok "Set up Database" # Setup App msg_info "Setup ${APPLICATION}" APACHE_LOG_DIR=/var/log/apache2 -RELEASE=$(curl -fsSL https://api.github.com/repos/Leantime/leantime/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -curl -fsSL -o "${RELEASE}.tar.gz" "https://github.com/Leantime/leantime/releases/download/${RELEASE}/Leantime-${RELEASE}.tar.gz" -mkdir -p "/opt/${APPLICATION}" -mkdir -p /etc/apache2/sites-enabled -tar xf "${RELEASE}.tar.gz" --strip-components=1 -C "/opt/${APPLICATION}" +fetch_and_deploy_gh_release "$APPLICATION" "Leantime/leantime" "prebuild" "latest" "/opt/${APPLICATION}" Leantime-v[0-9].[0-9].[0-9].tar.gz chown -R www-data:www-data "/opt/${APPLICATION}" chmod -R 750 "/opt/${APPLICATION}" @@ -99,7 +93,6 @@ sed -i -e "s/^;extension.\(curl\|fileinfo\|gd\|intl\|ldap\|mbstring\|exif\|mysql systemctl restart apache2 -echo "${RELEASE}" >/opt/"${APPLICATION}"_version.txt msg_ok "Setup ${APPLICATION}" motd_ssh @@ -107,7 +100,6 @@ customize # Cleanup msg_info "Cleaning up" -rm -f "${RELEASE}".tar.gz $STD apt-get -y autoremove $STD apt-get -y autoclean msg_ok "Cleaned" From dc0e63e7810b3854285d526b92f6f0a437087485 Mon Sep 17 00:00:00 2001 From: Stroopwafe1 <48443491+Stroopwafe1@users.noreply.github.com> Date: Fri, 27 Jun 2025 20:42:22 +0200 Subject: [PATCH 013/463] Chore: Remove remaining comments --- install/leantime-install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/install/leantime-install.sh b/install/leantime-install.sh index 475a464a..cd577289 100644 --- a/install/leantime-install.sh +++ b/install/leantime-install.sh @@ -50,7 +50,6 @@ $STD mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH } >>~/"$APPLICATION".creds msg_ok "Set up Database" -# Setup App msg_info "Setup ${APPLICATION}" APACHE_LOG_DIR=/var/log/apache2 fetch_and_deploy_gh_release "$APPLICATION" "Leantime/leantime" "prebuild" "latest" "/opt/${APPLICATION}" Leantime-v[0-9].[0-9].[0-9].tar.gz @@ -98,7 +97,6 @@ msg_ok "Setup ${APPLICATION}" motd_ssh customize -# Cleanup msg_info "Cleaning up" $STD apt-get -y autoremove $STD apt-get -y autoclean From 9989b15dda0871d0514e890df2a66c2586e13b7f Mon Sep 17 00:00:00 2001 From: Stroopwafe1 <48443491+Stroopwafe1@users.noreply.github.com> Date: Fri, 27 Jun 2025 20:45:56 +0200 Subject: [PATCH 014/463] Chore: Remove comment --- ct/leantime.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/leantime.sh b/ct/leantime.sh index cc58a765..f49c503a 100644 --- a/ct/leantime.sh +++ b/ct/leantime.sh @@ -25,7 +25,6 @@ function update_script() { check_container_storage check_container_resources - # Check if installation is present | -f for file, -d for folder if [[ ! -d /opt/${APP} ]]; then msg_error "No ${APP} Installation Found!" exit From e00e6c6bb6cbed653c780a60103737d62ef14247 Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 27 Jun 2025 16:11:29 -0700 Subject: [PATCH 015/463] fixed build links for dev --- misc/build.func | 1974 ++++++++++++++++++++++----------------------- misc/install.func | 4 +- 2 files changed, 989 insertions(+), 989 deletions(-) diff --git a/misc/build.func b/misc/build.func index 91bf98e0..351f5830 100644 --- a/misc/build.func +++ b/misc/build.func @@ -5,329 +5,329 @@ # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE variables() { - NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. - var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. - INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. - PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase - DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call. - METHOD="default" # sets the METHOD variable to "default", used for the API call. - RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable. - CT_TYPE=${var_unprivileged:-$CT_TYPE} + NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. + var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. + INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. + PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase + DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call. + METHOD="default" # sets the METHOD variable to "default", used for the API call. + RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable. + CT_TYPE=${var_unprivileged:-$CT_TYPE} } source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/api.func) if command -v curl >/dev/null 2>&1; then - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/core.func) - load_functions - #echo "(build.func) Loaded core.func via curl" + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/core.func) + load_functions + #echo "(build.func) Loaded core.func via curl" elif command -v wget >/dev/null 2>&1; then - source <(wget -qO- https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/core.func) - load_functions - #echo "(build.func) Loaded core.func via wget" + source <(wget -qO- https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/core.func) + load_functions + #echo "(build.func) Loaded core.func via wget" fi # This function enables error handling in the script by setting options and defining a trap for the ERR signal. catch_errors() { - set -Eeo pipefail - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + set -Eeo pipefail + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { - source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/api.func) - printf "\e[?25h" - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - post_update_to_api "failed" "${command}" - echo -e "\n$error_message\n" + source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/api.func) + printf "\e[?25h" + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + post_update_to_api "failed" "${command}" + echo -e "\n$error_message\n" - if [[ -n "$CT_ID" ]]; then - read -p "Remove this Container? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - pct stop "$CT_ID" &>/dev/null - pct destroy "$CT_ID" &>/dev/null - msg_ok "Removed this Container" + if [[ -n "$CT_ID" ]]; then + read -p "Remove this Container? " prompt + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + pct stop "$CT_ID" &>/dev/null + pct destroy "$CT_ID" &>/dev/null + msg_ok "Removed this Container" + fi fi - fi } # Check if the shell is using bash shell_check() { - if [[ "$(basename "$SHELL")" != "bash" ]]; then - clear - msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." - echo -e "\nExiting..." - sleep 2 - exit - fi + if [[ "$(basename "$SHELL")" != "bash" ]]; then + clear + msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." + echo -e "\nExiting..." + sleep 2 + exit + fi } # Run as root only root_check() { - if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then - clear - msg_error "Please run this script as root." - echo -e "\nExiting..." - sleep 2 - exit - fi + if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit + fi } # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { - if ! pveversion | grep -Eq "pve-manager/8\.[0-4](\.[0-9]+)*"; then - msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported" - echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." - echo -e "Exiting..." - sleep 2 - exit - fi + if ! pveversion | grep -Eq "pve-manager/8\.[0-4](\.[0-9]+)*"; then + msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported" + echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." + echo -e "Exiting..." + sleep 2 + exit + fi } # When a node is running tens of containers, it's possible to exceed the kernel's cryptographic key storage allocations. # These are tuneable, so verify if the currently deployment is approaching the limits, advise the user on how to tune the limits, and exit the script. # https://cleveruptime.com/docs/files/proc-key-users | https://docs.kernel.org/security/keys/core.html maxkeys_check() { - # Read kernel parameters - per_user_maxkeys=$(cat /proc/sys/kernel/keys/maxkeys 2>/dev/null || echo 0) - per_user_maxbytes=$(cat /proc/sys/kernel/keys/maxbytes 2>/dev/null || echo 0) + # Read kernel parameters + per_user_maxkeys=$(cat /proc/sys/kernel/keys/maxkeys 2>/dev/null || echo 0) + per_user_maxbytes=$(cat /proc/sys/kernel/keys/maxbytes 2>/dev/null || echo 0) - # Exit if kernel parameters are unavailable - if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then - echo -e "${CROSS}${RD} Error: Unable to read kernel parameters. Ensure proper permissions.${CL}" - exit 1 - fi + # Exit if kernel parameters are unavailable + if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then + echo -e "${CROSS}${RD} Error: Unable to read kernel parameters. Ensure proper permissions.${CL}" + exit 1 + fi - # Fetch key usage for user ID 100000 (typical for containers) - used_lxc_keys=$(awk '/100000:/ {print $2}' /proc/key-users 2>/dev/null || echo 0) - used_lxc_bytes=$(awk '/100000:/ {split($5, a, "/"); print a[1]}' /proc/key-users 2>/dev/null || echo 0) + # Fetch key usage for user ID 100000 (typical for containers) + used_lxc_keys=$(awk '/100000:/ {print $2}' /proc/key-users 2>/dev/null || echo 0) + used_lxc_bytes=$(awk '/100000:/ {split($5, a, "/"); print a[1]}' /proc/key-users 2>/dev/null || echo 0) - # Calculate thresholds and suggested new limits - threshold_keys=$((per_user_maxkeys - 100)) - threshold_bytes=$((per_user_maxbytes - 1000)) - new_limit_keys=$((per_user_maxkeys * 2)) - new_limit_bytes=$((per_user_maxbytes * 2)) + # Calculate thresholds and suggested new limits + threshold_keys=$((per_user_maxkeys - 100)) + threshold_bytes=$((per_user_maxbytes - 1000)) + new_limit_keys=$((per_user_maxkeys * 2)) + new_limit_bytes=$((per_user_maxbytes * 2)) - # Check if key or byte usage is near limits - failure=0 - if [[ "$used_lxc_keys" -gt "$threshold_keys" ]]; then - echo -e "${CROSS}${RD} Warning: Key usage is near the limit (${used_lxc_keys}/${per_user_maxkeys}).${CL}" - echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxkeys=${new_limit_keys}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." - failure=1 - fi - if [[ "$used_lxc_bytes" -gt "$threshold_bytes" ]]; then - echo -e "${CROSS}${RD} Warning: Key byte usage is near the limit (${used_lxc_bytes}/${per_user_maxbytes}).${CL}" - echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxbytes=${new_limit_bytes}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." - failure=1 - fi + # Check if key or byte usage is near limits + failure=0 + if [[ "$used_lxc_keys" -gt "$threshold_keys" ]]; then + echo -e "${CROSS}${RD} Warning: Key usage is near the limit (${used_lxc_keys}/${per_user_maxkeys}).${CL}" + echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxkeys=${new_limit_keys}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." + failure=1 + fi + if [[ "$used_lxc_bytes" -gt "$threshold_bytes" ]]; then + echo -e "${CROSS}${RD} Warning: Key byte usage is near the limit (${used_lxc_bytes}/${per_user_maxbytes}).${CL}" + echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxbytes=${new_limit_bytes}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." + failure=1 + fi - # Provide next steps if issues are detected - if [[ "$failure" -eq 1 ]]; then - echo -e "${INFO} To apply changes, run: ${BOLD}service procps force-reload${CL}" - exit 1 - fi + # Provide next steps if issues are detected + if [[ "$failure" -eq 1 ]]; then + echo -e "${INFO} To apply changes, run: ${BOLD}service procps force-reload${CL}" + exit 1 + fi - echo -e "${CM}${GN} All kernel key limits are within safe thresholds.${CL}" + echo -e "${CM}${GN} All kernel key limits are within safe thresholds.${CL}" } # This function checks the system architecture and exits if it's not "amd64". arch_check() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n" - echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" - echo -e "Exiting..." - sleep 2 - exit - fi + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n" + echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" + echo -e "Exiting..." + sleep 2 + exit + fi } # Function to get the current IP address based on the distribution get_current_ip() { - if [ -f /etc/os-release ]; then - # Check for Debian/Ubuntu (uses hostname -I) - if grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then - CURRENT_IP=$(hostname -I | awk '{print $1}') - # Check for Alpine (uses ip command) - elif grep -q 'ID=alpine' /etc/os-release; then - CURRENT_IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) - else - CURRENT_IP="Unknown" + if [ -f /etc/os-release ]; then + # Check for Debian/Ubuntu (uses hostname -I) + if grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then + CURRENT_IP=$(hostname -I | awk '{print $1}') + # Check for Alpine (uses ip command) + elif grep -q 'ID=alpine' /etc/os-release; then + CURRENT_IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) + else + CURRENT_IP="Unknown" + fi fi - fi - echo "$CURRENT_IP" + echo "$CURRENT_IP" } # Function to update the IP address in the MOTD file update_motd_ip() { - MOTD_FILE="/etc/motd" + MOTD_FILE="/etc/motd" - if [ -f "$MOTD_FILE" ]; then - # Remove existing IP Address lines to prevent duplication - sed -i '/IP Address:/d' "$MOTD_FILE" + if [ -f "$MOTD_FILE" ]; then + # Remove existing IP Address lines to prevent duplication + sed -i '/IP Address:/d' "$MOTD_FILE" - IP=$(get_current_ip) - # Add the new IP address - echo -e "${TAB}${NETWORK}${YW} IP Address: ${GN}${IP}${CL}" >>"$MOTD_FILE" - fi + IP=$(get_current_ip) + # Add the new IP address + echo -e "${TAB}${NETWORK}${YW} IP Address: ${GN}${IP}${CL}" >>"$MOTD_FILE" + fi } # This function checks if the script is running through SSH and prompts the user to confirm if they want to proceed or exit. ssh_check() { - if [ -n "${SSH_CLIENT:+x}" ]; then - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's advisable to utilize the Proxmox shell rather than SSH, as there may be potential complications with variable retrieval. Proceed using SSH?" 10 72; then - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Proceed using SSH" "You've chosen to proceed using SSH. If any issues arise, please run the script in the Proxmox shell before creating a repository issue." 10 72 - else - clear - echo "Exiting due to SSH usage. Please consider using the Proxmox shell." - exit + if [ -n "${SSH_CLIENT:+x}" ]; then + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's advisable to utilize the Proxmox shell rather than SSH, as there may be potential complications with variable retrieval. Proceed using SSH?" 10 72; then + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Proceed using SSH" "You've chosen to proceed using SSH. If any issues arise, please run the script in the Proxmox shell before creating a repository issue." 10 72 + else + clear + echo "Exiting due to SSH usage. Please consider using the Proxmox shell." + exit + fi fi - fi } select_storage() { - local CLASS=$1 CONTENT CONTENT_LABEL - case $CLASS in - container) - CONTENT='rootdir' - CONTENT_LABEL='Container' - ;; - template) - CONTENT='vztmpl' - CONTENT_LABEL='Template' - ;; - iso) - CONTENT='iso' - CONTENT_LABEL='ISO image' - ;; - images) - CONTENT='images' - CONTENT_LABEL='VM Disk image' - ;; - backup) - CONTENT='backup' - CONTENT_LABEL='Backup' - ;; - snippets) - CONTENT='snippets' - CONTENT_LABEL='Snippets' - ;; - *) - msg_error "Invalid storage class '$CLASS'." - exit 201 - ;; - esac + local CLASS=$1 CONTENT CONTENT_LABEL + case $CLASS in + container) + CONTENT='rootdir' + CONTENT_LABEL='Container' + ;; + template) + CONTENT='vztmpl' + CONTENT_LABEL='Template' + ;; + iso) + CONTENT='iso' + CONTENT_LABEL='ISO image' + ;; + images) + CONTENT='images' + CONTENT_LABEL='VM Disk image' + ;; + backup) + CONTENT='backup' + CONTENT_LABEL='Backup' + ;; + snippets) + CONTENT='snippets' + CONTENT_LABEL='Snippets' + ;; + *) + msg_error "Invalid storage class '$CLASS'." + exit 201 + ;; + esac - command -v whiptail >/dev/null || { - msg_error "whiptail missing." - exit 220 - } - command -v numfmt >/dev/null || { - msg_error "numfmt missing." - exit 221 - } + command -v whiptail >/dev/null || { + msg_error "whiptail missing." + exit 220 + } + command -v numfmt >/dev/null || { + msg_error "numfmt missing." + exit 221 + } - local -a MENU - while read -r line; do - local TAG=$(echo "$line" | awk '{print $1}') - local TYPE=$(echo "$line" | awk '{printf "%-10s", $2}') - local FREE=$(echo "$line" | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf "%9sB", $6}') - MENU+=("$TAG" "Type: $TYPE Free: $FREE" "OFF") - done < <(pvesm status -content "$CONTENT" | awk 'NR>1') + local -a MENU + while read -r line; do + local TAG=$(echo "$line" | awk '{print $1}') + local TYPE=$(echo "$line" | awk '{printf "%-10s", $2}') + local FREE=$(echo "$line" | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf "%9sB", $6}') + MENU+=("$TAG" "Type: $TYPE Free: $FREE" "OFF") + done < <(pvesm status -content "$CONTENT" | awk 'NR>1') - if [ ${#MENU[@]} -eq 0 ]; then - msg_error "No storage found for content type '$CONTENT'." - exit 203 - fi + if [ ${#MENU[@]} -eq 0 ]; then + msg_error "No storage found for content type '$CONTENT'." + exit 203 + fi - if [ $((${#MENU[@]} / 3)) -eq 1 ]; then - echo "${MENU[0]}" - return - fi + if [ $((${#MENU[@]} / 3)) -eq 1 ]; then + echo "${MENU[0]}" + return + fi - local STORAGE - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ - 16 70 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { - msg_error "Storage selection cancelled by user." - exit 202 - } - echo "$STORAGE" + local STORAGE + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ + "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ + 16 70 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { + msg_error "Storage selection cancelled by user." + exit 202 + } + echo "$STORAGE" } manage_default_storage() { - local file="/usr/local/community-scripts/default_storage" - mkdir -p /usr/local/community-scripts + local file="/usr/local/community-scripts/default_storage" + mkdir -p /usr/local/community-scripts - local tmpl=$(select_storage template) - local cont=$(select_storage container) + local tmpl=$(select_storage template) + local cont=$(select_storage container) - cat <"$file" + cat <"$file" TEMPLATE_STORAGE=$tmpl CONTAINER_STORAGE=$cont EOF - msg_ok "Default Storage set: Template=${BL}$tmpl${CL} ${GN}|${CL} Container=${BL}$cont${CL}" - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --msgbox "Default Storage set:\n\nTemplate: $tmpl\nContainer: $cont" 10 58 + msg_ok "Default Storage set: Template=${BL}$tmpl${CL} ${GN}|${CL} Container=${BL}$cont${CL}" + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --msgbox "Default Storage set:\n\nTemplate: $tmpl\nContainer: $cont" 10 58 } base_settings() { - # Default Settings - CT_TYPE="1" - DISK_SIZE="4" - CORE_COUNT="1" - RAM_SIZE="1024" - VERBOSE="${1:-no}" - PW="" - CT_ID=$NEXTID - HN=$NSAPP - BRG="vmbr0" - NET="dhcp" - IPV6_METHOD="none" - IPV6_STATIC="" - GATE="" - APT_CACHER="" - APT_CACHER_IP="" - #DISABLEIP6="no" - MTU="" - SD="" - NS="" - MAC="" - VLAN="" - SSH="no" - SSH_AUTHORIZED_KEY="" - UDHCPC_FIX="" - TAGS="community-script;" - ENABLE_FUSE="${1:-no}" - ENABLE_TUN="${1:-no}" + # Default Settings + CT_TYPE="1" + DISK_SIZE="4" + CORE_COUNT="1" + RAM_SIZE="1024" + VERBOSE="${1:-no}" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + BRG="vmbr0" + NET="dhcp" + IPV6_METHOD="none" + IPV6_STATIC="" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + #DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + SSH_AUTHORIZED_KEY="" + UDHCPC_FIX="" + TAGS="community-script;" + ENABLE_FUSE="${1:-no}" + ENABLE_TUN="${1:-no}" - # Override default settings with variables from ct script - CT_TYPE=${var_unprivileged:-$CT_TYPE} - DISK_SIZE=${var_disk:-$DISK_SIZE} - CORE_COUNT=${var_cpu:-$CORE_COUNT} - RAM_SIZE=${var_ram:-$RAM_SIZE} - VERB=${var_verbose:-$VERBOSE} - TAGS="${TAGS}${var_tags:-}" - ENABLE_FUSE="${var_fuse:-$ENABLE_FUSE}" - ENABLE_TUN="${var_tun:-$ENABLE_TUN}" + # Override default settings with variables from ct script + CT_TYPE=${var_unprivileged:-$CT_TYPE} + DISK_SIZE=${var_disk:-$DISK_SIZE} + CORE_COUNT=${var_cpu:-$CORE_COUNT} + RAM_SIZE=${var_ram:-$RAM_SIZE} + VERB=${var_verbose:-$VERBOSE} + TAGS="${TAGS}${var_tags:-}" + ENABLE_FUSE="${var_fuse:-$ENABLE_FUSE}" + ENABLE_TUN="${var_tun:-$ENABLE_TUN}" - # Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts - if [ -z "$var_os" ]; then - var_os="debian" - fi - if [ -z "$var_version" ]; then - var_version="12" - fi + # Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts + if [ -z "$var_os" ]; then + var_os="debian" + fi + if [ -z "$var_version" ]; then + var_version="12" + fi } write_config() { - mkdir -p /opt/community-scripts - # This function writes the configuration to a file. - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Write configfile" --yesno "Do you want to write the selections to a config file?" 10 60; then - FILEPATH="/opt/community-scripts/${NSAPP}.conf" - if [[ ! -f $FILEPATH ]]; then - cat <"$FILEPATH" + mkdir -p /opt/community-scripts + # This function writes the configuration to a file. + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Write configfile" --yesno "Do you want to write the selections to a config file?" 10 60; then + FILEPATH="/opt/community-scripts/${NSAPP}.conf" + if [[ ! -f $FILEPATH ]]; then + cat <"$FILEPATH" # ${NSAPP} Configuration File # Generated on $(date) @@ -353,12 +353,12 @@ NS="${NS:-none}" NET="${NET}" EOF - echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" - else - echo -e "${INFO}${BOLD}${RD}Configuration file already exists at ${FILEPATH}${CL}" - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Overwrite configfile" --yesno "Do you want to overwrite the existing config file?" 10 60; then - rm -f "$FILEPATH" - cat <"$FILEPATH" + echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" + else + echo -e "${INFO}${BOLD}${RD}Configuration file already exists at ${FILEPATH}${CL}" + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Overwrite configfile" --yesno "Do you want to overwrite the existing config file?" 10 60; then + rm -f "$FILEPATH" + cat <"$FILEPATH" # ${NSAPP} Configuration File # Generated on $(date) @@ -384,516 +384,516 @@ NS="${NS:-none}" NET="${NET}" EOF - echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" - else - echo -e "${INFO}${BOLD}${RD}Configuration file not overwritten${CL}" - fi + echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" + else + echo -e "${INFO}${BOLD}${RD}Configuration file not overwritten${CL}" + fi + fi fi - fi } # This function displays the default values for various settings. echo_default() { - # Convert CT_TYPE to description - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi + # Convert CT_TYPE to description + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi - # Output the selected values with icons - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" - echo -e "${OS}${BOLD}${DGN}Operating System: $var_os | Version: $var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB | ${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT} | ${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - if [ "$VERB" == "yes" ]; then - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}" - fi - echo -e "${CREATING}${BOLD}${BL}Creating a ${APP} LXC using the above default settings${CL}" - echo -e " " + # Output the selected values with icons + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" + echo -e "${OS}${BOLD}${DGN}Operating System: $var_os | Version: $var_version${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB | ${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT} | ${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" + if [ "$VERB" == "yes" ]; then + echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}" + fi + echo -e "${CREATING}${BOLD}${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e " " } # This function is called when the user decides to exit the script. It clears the screen and displays an exit message. exit_script() { - clear - echo -e "\n${CROSS}${RD}User exited script${CL}\n" - exit + clear + echo -e "\n${CROSS}${RD}User exited script${CL}\n" + exit } # This function allows the user to configure advanced settings for the script. advanced_settings() { - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 - # Setting Default Tag for Advanced Settings - TAGS="community-script;${var_tags:-}" - CT_DEFAULT_TYPE="${CT_TYPE}" - CT_TYPE="" - while [ -z "$CT_TYPE" ]; do - if [ "$CT_DEFAULT_TYPE" == "1" ]; then - if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - if [ -n "$CT_TYPE" ]; then - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os | ${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 + # Setting Default Tag for Advanced Settings + TAGS="community-script;${var_tags:-}" + CT_DEFAULT_TYPE="${CT_TYPE}" + CT_TYPE="" + while [ -z "$CT_TYPE" ]; do + if [ "$CT_DEFAULT_TYPE" == "1" ]; then + if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then + if [ -n "$CT_TYPE" ]; then + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os | ${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" + fi + else + exit_script + fi fi - else + if [ "$CT_DEFAULT_TYPE" == "0" ]; then + if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3); then + if [ -n "$CT_TYPE" ]; then + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" + echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" + fi + else + exit_script + fi + fi + done + + while true; do + if PW1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD (leave blank for automatic login)" 3>&1 1>&2 2>&3); then + # Empty = Autologin + if [[ -z "$PW1" ]]; then + PW="" + PW1="Automatic Login" + echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}$PW1${CL}" + break + fi + + # Invalid: contains spaces + if [[ "$PW1" == *" "* ]]; then + whiptail --msgbox "Password cannot contain spaces." 8 58 + continue + fi + + # Invalid: too short + if ((${#PW1} < 5)); then + whiptail --msgbox "Password must be at least 5 characters." 8 58 + continue + fi + + # Confirm password + if PW2=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nVerify Root Password" 9 58 --title "PASSWORD VERIFICATION" 3>&1 1>&2 2>&3); then + if [[ "$PW1" == "$PW2" ]]; then + PW="-password $PW1" + echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}********${CL}" + break + else + whiptail --msgbox "Passwords do not match. Please try again." 8 58 + fi + else + exit_script + fi + else + exit_script + fi + done + + if CT_ID=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 "$NEXTID" --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi + else exit_script - fi fi - if [ "$CT_DEFAULT_TYPE" == "0" ]; then - if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3); then - if [ -n "$CT_TYPE" ]; then - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" + + while true; do + if CT_NAME=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 "$NSAPP" --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo "${CT_NAME,,}" | tr -d ' ') + fi + # Hostname validate (RFC 1123) + if [[ "$HN" =~ ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ ]]; then + echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}" + break + else + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --msgbox "❌ Invalid hostname: '$HN'\n\nOnly lowercase letters, digits and hyphens (-) are allowed.\nUnderscores (_) or other characters are not permitted!" 10 70 + fi + else + exit_script fi - else + done + + while true; do + DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GB" 8 58 "$var_disk" --title "DISK SIZE" 3>&1 1>&2 2>&3) || exit_script + + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + fi + + if [[ "$DISK_SIZE" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" + break + else + whiptail --msgbox "Disk size must be a positive integer!" 8 58 + fi + done + + while true; do + CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ + --inputbox "Allocate CPU Cores" 8 58 "$var_cpu" --title "CORE COUNT" 3>&1 1>&2 2>&3) || exit_script + + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + fi + + if [[ "$CORE_COUNT" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}" + break + else + whiptail --msgbox "CPU core count must be a positive integer!" 8 58 + fi + done + + while true; do + RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ + --inputbox "Allocate RAM in MiB" 8 58 "$var_ram" --title "RAM" 3>&1 1>&2 2>&3) || exit_script + + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + fi + + if [[ "$RAM_SIZE" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" + break + else + whiptail --msgbox "RAM size must be a positive integer!" 8 58 + fi + done + + IFACE_FILEPATH_LIST="/etc/network/interfaces"$'\n'$(find "/etc/network/interfaces.d/" -type f) + BRIDGES="" + OLD_IFS=$IFS + IFS=$'\n' + for iface_filepath in ${IFACE_FILEPATH_LIST}; do + + iface_indexes_tmpfile=$(mktemp -q -u '.iface-XXXX') + (grep -Pn '^\s*iface' "${iface_filepath}" | cut -d':' -f1 && wc -l "${iface_filepath}" | cut -d' ' -f1) | awk 'FNR==1 {line=$0; next} {print line":"$0-1; line=$0}' >"${iface_indexes_tmpfile}" || true + + if [ -f "${iface_indexes_tmpfile}" ]; then + + while read -r pair; do + start=$(echo "${pair}" | cut -d':' -f1) + end=$(echo "${pair}" | cut -d':' -f2) + + if awk "NR >= ${start} && NR <= ${end}" "${iface_filepath}" | grep -qP '^\s*(bridge[-_](ports|stp|fd|vlan-aware|vids)|ovs_type\s+OVSBridge)\b'; then + iface_name=$(sed "${start}q;d" "${iface_filepath}" | awk '{print $2}') + BRIDGES="${iface_name}"$'\n'"${BRIDGES}" + fi + + done <"${iface_indexes_tmpfile}" + rm -f "${iface_indexes_tmpfile}" + fi + + done + IFS=$OLD_IFS + BRIDGES=$(echo "$BRIDGES" | grep -v '^\s*$' | sort | uniq) + if [[ -z "$BRIDGES" ]]; then + BRG="vmbr0" + echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" + else + BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --menu "Select network bridge:" 15 40 6 $(echo "$BRIDGES" | awk '{print $0, "Bridge"}') 3>&1 1>&2 2>&3) + if [[ -z "$BRG" ]]; then + exit_script + else + echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" + fi + fi + + # IPv4 methods: dhcp, static, none + while true; do + IPV4_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --title "IPv4 Address Management" \ + --menu "Select IPv4 Address Assignment Method:" 12 60 2 \ + "dhcp" "Automatic (DHCP, recommended)" \ + "static" "Static (manual entry)" \ + 3>&1 1>&2 2>&3) + + exit_status=$? + if [ $exit_status -ne 0 ]; then + exit_script + fi + + case "$IPV4_METHOD" in + dhcp) + NET="dhcp" + GATE="" + echo -e "${NETWORK}${BOLD}${DGN}IPv4: DHCP${CL}" + break + ;; + static) + # Static: call and validate CIDR address + while true; do + NET=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --inputbox "Enter Static IPv4 CIDR Address (e.g. 192.168.100.50/24)" 8 58 "" \ + --title "IPv4 ADDRESS" 3>&1 1>&2 2>&3) + if [ -z "$NET" ]; then + whiptail --msgbox "IPv4 address must not be empty." 8 58 + continue + elif [[ "$NET" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then + echo -e "${NETWORK}${BOLD}${DGN}IPv4 Address: ${BGN}$NET${CL}" + break + else + whiptail --msgbox "$NET is not a valid IPv4 CIDR address. Please enter a correct value!" 8 58 + fi + done + + # call and validate Gateway + while true; do + GATE1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --inputbox "Enter Gateway IP address for static IPv4" 8 58 "" \ + --title "Gateway IP" 3>&1 1>&2 2>&3) + if [ -z "$GATE1" ]; then + whiptail --msgbox "Gateway IP address cannot be empty." 8 58 + elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + whiptail --msgbox "Invalid Gateway IP address format." 8 58 + else + GATE=",gw=$GATE1" + echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}$GATE1${CL}" + break + fi + done + break + ;; + esac + done + + # IPv6 Address Management selection + while true; do + IPV6_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --menu \ + "Select IPv6 Address Management Type:" 15 58 4 \ + "auto" "SLAAC/AUTO (recommended, default)" \ + "dhcp" "DHCPv6" \ + "static" "Static (manual entry)" \ + "none" "Disabled" \ + --default-item "auto" 3>&1 1>&2 2>&3) + [ $? -ne 0 ] && exit_script + + case "$IPV6_METHOD" in + auto) + echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}SLAAC/AUTO${CL}" + IPV6_ADDR="" + IPV6_GATE="" + break + ;; + dhcp) + echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}DHCPv6${CL}" + IPV6_ADDR="dhcp" + IPV6_GATE="" + break + ;; + static) + # Ask for static IPv6 address (CIDR notation, e.g., 2001:db8::1234/64) + while true; do + IPV6_ADDR=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ + "Set a static IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 "" \ + --title "IPv6 STATIC ADDRESS" 3>&1 1>&2 2>&3) || exit_script + if [[ "$IPV6_ADDR" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+(/[0-9]{1,3})$ ]]; then + echo -e "${NETWORK}${BOLD}${DGN}IPv6 Address: ${BGN}$IPV6_ADDR${CL}" + break + else + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ + "$IPV6_ADDR is an invalid IPv6 CIDR address. Please enter a valid IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 + fi + done + # Optional: ask for IPv6 gateway for static config + while true; do + IPV6_GATE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ + "Enter IPv6 gateway address (optional, leave blank for none)" 8 58 "" --title "IPv6 GATEWAY" 3>&1 1>&2 2>&3) + if [ -z "$IPV6_GATE" ]; then + IPV6_GATE="" + break + elif [[ "$IPV6_GATE" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+$ ]]; then + break + else + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ + "Invalid IPv6 gateway format." 8 58 + fi + done + break + ;; + none) + echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}Disabled${CL}" + IPV6_ADDR="none" + IPV6_GATE="" + break + ;; + *) + exit_script + ;; + esac + done + + if [ "$var_os" == "alpine" ]; then + APT_CACHER="" + APT_CACHER_IP="" + else + if APT_CACHER_IP=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for none)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then + APT_CACHER="${APT_CACHER_IP:+yes}" + echo -e "${NETWORK}${BOLD}${DGN}APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" + else + exit_script + fi + fi + + # if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + # DISABLEIP6="yes" + # else + # DISABLEIP6="no" + # fi + # echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + + if MTU1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default [The MTU of your selected vmbr, default is 1500])" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$MTU1" ]; then + MTU1="Default" + MTU="" + else + MTU=",mtu=$MTU1" + fi + echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}" + else exit_script - fi fi - done - while true; do - if PW1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD (leave blank for automatic login)" 3>&1 1>&2 2>&3); then - # Empty = Autologin - if [[ -z "$PW1" ]]; then - PW="" - PW1="Automatic Login" - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}$PW1${CL}" - break - fi - - # Invalid: contains spaces - if [[ "$PW1" == *" "* ]]; then - whiptail --msgbox "Password cannot contain spaces." 8 58 - continue - fi - - # Invalid: too short - if ((${#PW1} < 5)); then - whiptail --msgbox "Password must be at least 5 characters." 8 58 - continue - fi - - # Confirm password - if PW2=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nVerify Root Password" 9 58 --title "PASSWORD VERIFICATION" 3>&1 1>&2 2>&3); then - if [[ "$PW1" == "$PW2" ]]; then - PW="-password $PW1" - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}********${CL}" - break + if SD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then + if [ -z "$SD" ]; then + SX=Host + SD="" else - whiptail --msgbox "Passwords do not match. Please try again." 8 58 + SX=$SD + SD="-searchdomain=$SD" fi - else + echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}$SX${CL}" + else exit_script - fi - else - exit_script - fi - done - - if CT_ID=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 "$NEXTID" --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi - else - exit_script - fi - - while true; do - if CT_NAME=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 "$NSAPP" --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo "${CT_NAME,,}" | tr -d ' ') - fi - # Hostname validate (RFC 1123) - if [[ "$HN" =~ ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ ]]; then - echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}" - break - else - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --msgbox "❌ Invalid hostname: '$HN'\n\nOnly lowercase letters, digits and hyphens (-) are allowed.\nUnderscores (_) or other characters are not permitted!" 10 70 - fi - else - exit_script - fi - done - - while true; do - DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GB" 8 58 "$var_disk" --title "DISK SIZE" 3>&1 1>&2 2>&3) || exit_script - - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" fi - if [[ "$DISK_SIZE" =~ ^[1-9][0-9]*$ ]]; then - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" - break - else - whiptail --msgbox "Disk size must be a positive integer!" 8 58 - fi - done - - while true; do - CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ - --inputbox "Allocate CPU Cores" 8 58 "$var_cpu" --title "CORE COUNT" 3>&1 1>&2 2>&3) || exit_script - - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - fi - - if [[ "$CORE_COUNT" =~ ^[1-9][0-9]*$ ]]; then - echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}" - break - else - whiptail --msgbox "CPU core count must be a positive integer!" 8 58 - fi - done - - while true; do - RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ - --inputbox "Allocate RAM in MiB" 8 58 "$var_ram" --title "RAM" 3>&1 1>&2 2>&3) || exit_script - - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - fi - - if [[ "$RAM_SIZE" =~ ^[1-9][0-9]*$ ]]; then - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - break - else - whiptail --msgbox "RAM size must be a positive integer!" 8 58 - fi - done - - IFACE_FILEPATH_LIST="/etc/network/interfaces"$'\n'$(find "/etc/network/interfaces.d/" -type f) - BRIDGES="" - OLD_IFS=$IFS - IFS=$'\n' - for iface_filepath in ${IFACE_FILEPATH_LIST}; do - - iface_indexes_tmpfile=$(mktemp -q -u '.iface-XXXX') - (grep -Pn '^\s*iface' "${iface_filepath}" | cut -d':' -f1 && wc -l "${iface_filepath}" | cut -d' ' -f1) | awk 'FNR==1 {line=$0; next} {print line":"$0-1; line=$0}' >"${iface_indexes_tmpfile}" || true - - if [ -f "${iface_indexes_tmpfile}" ]; then - - while read -r pair; do - start=$(echo "${pair}" | cut -d':' -f1) - end=$(echo "${pair}" | cut -d':' -f2) - - if awk "NR >= ${start} && NR <= ${end}" "${iface_filepath}" | grep -qP '^\s*(bridge[-_](ports|stp|fd|vlan-aware|vids)|ovs_type\s+OVSBridge)\b'; then - iface_name=$(sed "${start}q;d" "${iface_filepath}" | awk '{print $2}') - BRIDGES="${iface_name}"$'\n'"${BRIDGES}" - fi - - done <"${iface_indexes_tmpfile}" - rm -f "${iface_indexes_tmpfile}" - fi - - done - IFS=$OLD_IFS - BRIDGES=$(echo "$BRIDGES" | grep -v '^\s*$' | sort | uniq) - if [[ -z "$BRIDGES" ]]; then - BRG="vmbr0" - echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" - else - BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --menu "Select network bridge:" 15 40 6 $(echo "$BRIDGES" | awk '{print $0, "Bridge"}') 3>&1 1>&2 2>&3) - if [[ -z "$BRG" ]]; then - exit_script - else - echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" - fi - fi - - # IPv4 methods: dhcp, static, none - while true; do - IPV4_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --title "IPv4 Address Management" \ - --menu "Select IPv4 Address Assignment Method:" 12 60 2 \ - "dhcp" "Automatic (DHCP, recommended)" \ - "static" "Static (manual entry)" \ - 3>&1 1>&2 2>&3) - - exit_status=$? - if [ $exit_status -ne 0 ]; then - exit_script - fi - - case "$IPV4_METHOD" in - dhcp) - NET="dhcp" - GATE="" - echo -e "${NETWORK}${BOLD}${DGN}IPv4: DHCP${CL}" - break - ;; - static) - # Static: call and validate CIDR address - while true; do - NET=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --inputbox "Enter Static IPv4 CIDR Address (e.g. 192.168.100.50/24)" 8 58 "" \ - --title "IPv4 ADDRESS" 3>&1 1>&2 2>&3) - if [ -z "$NET" ]; then - whiptail --msgbox "IPv4 address must not be empty." 8 58 - continue - elif [[ "$NET" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then - echo -e "${NETWORK}${BOLD}${DGN}IPv4 Address: ${BGN}$NET${CL}" - break + if NX=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z "$NX" ]; then + NX=Host + NS="" else - whiptail --msgbox "$NET is not a valid IPv4 CIDR address. Please enter a correct value!" 8 58 + NS="-nameserver=$NX" fi - done + echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}$NX${CL}" + else + exit_script + fi - # call and validate Gateway - while true; do - GATE1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --inputbox "Enter Gateway IP address for static IPv4" 8 58 "" \ - --title "Gateway IP" 3>&1 1>&2 2>&3) - if [ -z "$GATE1" ]; then - whiptail --msgbox "Gateway IP address cannot be empty." 8 58 - elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then - whiptail --msgbox "Invalid Gateway IP address format." 8 58 + if [ "$var_os" == "alpine" ] && [ "$NET" == "dhcp" ] && [ "$NX" != "Host" ]; then + UDHCPC_FIX="yes" + else + UDHCPC_FIX="no" + fi + export UDHCPC_FIX + + if MAC1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a MAC Address(leave blank for generated MAC)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z "$MAC1" ]; then + MAC1="Default" + MAC="" else - GATE=",gw=$GATE1" - echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}$GATE1${CL}" - break + MAC=",hwaddr=$MAC1" + echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}" fi - done - break - ;; - esac - done + else + exit_script + fi - # IPv6 Address Management selection - while true; do - IPV6_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --menu \ - "Select IPv6 Address Management Type:" 15 58 4 \ - "auto" "SLAAC/AUTO (recommended, default)" \ - "dhcp" "DHCPv6" \ - "static" "Static (manual entry)" \ - "none" "Disabled" \ - --default-item "auto" 3>&1 1>&2 2>&3) - [ $? -ne 0 ] && exit_script - - case "$IPV6_METHOD" in - auto) - echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}SLAAC/AUTO${CL}" - IPV6_ADDR="" - IPV6_GATE="" - break - ;; - dhcp) - echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}DHCPv6${CL}" - IPV6_ADDR="dhcp" - IPV6_GATE="" - break - ;; - static) - # Ask for static IPv6 address (CIDR notation, e.g., 2001:db8::1234/64) - while true; do - IPV6_ADDR=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ - "Set a static IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 "" \ - --title "IPv6 STATIC ADDRESS" 3>&1 1>&2 2>&3) || exit_script - if [[ "$IPV6_ADDR" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+(/[0-9]{1,3})$ ]]; then - echo -e "${NETWORK}${BOLD}${DGN}IPv6 Address: ${BGN}$IPV6_ADDR${CL}" - break + if VLAN1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for no VLAN)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then + if [ -z "$VLAN1" ]; then + VLAN1="Default" + VLAN="" else - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ - "$IPV6_ADDR is an invalid IPv6 CIDR address. Please enter a valid IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 + VLAN=",tag=$VLAN1" fi - done - # Optional: ask for IPv6 gateway for static config - while true; do - IPV6_GATE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ - "Enter IPv6 gateway address (optional, leave blank for none)" 8 58 "" --title "IPv6 GATEWAY" 3>&1 1>&2 2>&3) - if [ -z "$IPV6_GATE" ]; then - IPV6_GATE="" - break - elif [[ "$IPV6_GATE" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+$ ]]; then - break + echo -e "${VLANTAG}${BOLD}${DGN}Vlan: ${BGN}$VLAN1${CL}" + else + exit_script + fi + + if ADV_TAGS=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Custom Tags?[If you remove all, there will be no tags!]" 8 58 "${TAGS}" --title "Advanced Tags" 3>&1 1>&2 2>&3); then + if [ -n "${ADV_TAGS}" ]; then + ADV_TAGS=$(echo "$ADV_TAGS" | tr -d '[:space:]') + TAGS="${ADV_TAGS}" else - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ - "Invalid IPv6 gateway format." 8 58 + TAGS=";" fi - done - break - ;; - none) - echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}Disabled${CL}" - IPV6_ADDR="none" - IPV6_GATE="" - break - ;; - *) - exit_script - ;; - esac - done - - if [ "$var_os" == "alpine" ]; then - APT_CACHER="" - APT_CACHER_IP="" - else - if APT_CACHER_IP=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for none)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then - APT_CACHER="${APT_CACHER_IP:+yes}" - echo -e "${NETWORK}${BOLD}${DGN}APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" + echo -e "${NETWORK}${BOLD}${DGN}Tags: ${BGN}$TAGS${CL}" else - exit_script + exit_script fi - fi - # if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - # DISABLEIP6="yes" - # else - # DISABLEIP6="no" - # fi - # echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "SSH Authorized key for root (leave empty for none)" 8 58 --title "SSH Key" 3>&1 1>&2 2>&3)" - if MTU1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default [The MTU of your selected vmbr, default is 1500])" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$MTU1" ]; then - MTU1="Default" - MTU="" + if [[ -z "${SSH_AUTHORIZED_KEY}" ]]; then + SSH_AUTHORIZED_KEY="" + fi + + if [[ "$PW" == -password* || -n "$SSH_AUTHORIZED_KEY" ]]; then + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" + else + SSH="no" + fi + echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" else - MTU=",mtu=$MTU1" + SSH="no" + echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" fi - echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}" - else - exit_script - fi - if SD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z "$SD" ]; then - SX=Host - SD="" + # if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "FUSE Support" --yesno "Enable FUSE support?\nRequired for tools like rclone, mergerfs, AppImage, etc." 10 58); then + # ENABLE_FUSE="yes" + # else + # ENABLE_FUSE="no" + # fi + # echo -e "${FUSE}${BOLD}${DGN}Enable FUSE Support: ${BGN}$ENABLE_FUSE${CL}" + + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERBOSE="yes" else - SX=$SD - SD="-searchdomain=$SD" + VERBOSE="no" fi - echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}$SX${CL}" - else - exit_script - fi + echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERBOSE${CL}" - if NX=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z "$NX" ]; then - NX=Host - NS="" + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + write_config else - NS="-nameserver=$NX" + clear + header_info + echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" + advanced_settings fi - echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}$NX${CL}" - else - exit_script - fi - - if [ "$var_os" == "alpine" ] && [ "$NET" == "dhcp" ] && [ "$NX" != "Host" ]; then - UDHCPC_FIX="yes" - else - UDHCPC_FIX="no" - fi - export UDHCPC_FIX - - if MAC1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a MAC Address(leave blank for generated MAC)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z "$MAC1" ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}" - fi - else - exit_script - fi - - if VLAN1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for no VLAN)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z "$VLAN1" ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${VLANTAG}${BOLD}${DGN}Vlan: ${BGN}$VLAN1${CL}" - else - exit_script - fi - - if ADV_TAGS=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Custom Tags?[If you remove all, there will be no tags!]" 8 58 "${TAGS}" --title "Advanced Tags" 3>&1 1>&2 2>&3); then - if [ -n "${ADV_TAGS}" ]; then - ADV_TAGS=$(echo "$ADV_TAGS" | tr -d '[:space:]') - TAGS="${ADV_TAGS}" - else - TAGS=";" - fi - echo -e "${NETWORK}${BOLD}${DGN}Tags: ${BGN}$TAGS${CL}" - else - exit_script - fi - - SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "SSH Authorized key for root (leave empty for none)" 8 58 --title "SSH Key" 3>&1 1>&2 2>&3)" - - if [[ -z "${SSH_AUTHORIZED_KEY}" ]]; then - SSH_AUTHORIZED_KEY="" - fi - - if [[ "$PW" == -password* || -n "$SSH_AUTHORIZED_KEY" ]]; then - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" - else - SSH="no" - fi - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - else - SSH="no" - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - fi - - # if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "FUSE Support" --yesno "Enable FUSE support?\nRequired for tools like rclone, mergerfs, AppImage, etc." 10 58); then - # ENABLE_FUSE="yes" - # else - # ENABLE_FUSE="no" - # fi - # echo -e "${FUSE}${BOLD}${DGN}Enable FUSE Support: ${BGN}$ENABLE_FUSE${CL}" - - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERBOSE="yes" - else - VERBOSE="no" - fi - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERBOSE${CL}" - - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - write_config - else - clear - header_info - echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" - advanced_settings - fi } diagnostics_check() { - if ! [ -d "/usr/local/community-scripts" ]; then - mkdir -p /usr/local/community-scripts - fi + if ! [ -d "/usr/local/community-scripts" ]; then + mkdir -p /usr/local/community-scripts + fi - if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then - cat </usr/local/community-scripts/diagnostics + if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then + cat </usr/local/community-scripts/diagnostics DIAGNOSTICS=yes #This file is used to store the diagnostics settings for the Community-Scripts API. @@ -918,9 +918,9 @@ DIAGNOSTICS=yes #"status" #If you have any concerns, please review the source code at /misc/build.func EOF - DIAGNOSTICS="yes" - else - cat </usr/local/community-scripts/diagnostics + DIAGNOSTICS="yes" + else + cat </usr/local/community-scripts/diagnostics DIAGNOSTICS=no #This file is used to store the diagnostics settings for the Community-Scripts API. @@ -945,240 +945,240 @@ DIAGNOSTICS=no #"status" #If you have any concerns, please review the source code at /misc/build.func EOF - DIAGNOSTICS="no" - fi - else - DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' /usr/local/community-scripts/diagnostics) + DIAGNOSTICS="no" + fi + else + DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' /usr/local/community-scripts/diagnostics) - fi + fi } install_script() { - pve_check - shell_check - root_check - arch_check - ssh_check - maxkeys_check - diagnostics_check + pve_check + shell_check + root_check + arch_check + ssh_check + maxkeys_check + diagnostics_check - if systemctl is-active -q ping-instances.service; then - systemctl -q stop ping-instances.service - fi - NEXTID=$(pvesh get /cluster/nextid) - timezone=$(cat /etc/timezone) - header_info - while true; do - - CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SETTINGS" --menu "Choose an option:" \ - 20 60 7 \ - "1" "Default Settings" \ - "2" "Default Settings (with verbose)" \ - "3" "Advanced Settings" \ - "4" "Use Config File" \ - "5" "Manage Default Storage" \ - "6" "Diagnostic Settings" \ - "7" "Exit" --nocancel --default-item "1" 3>&1 1>&2 2>&3) - - if [ $? -ne 0 ]; then - echo -e "${CROSS}${RD} Menu canceled. Exiting.${CL}" - exit 0 + if systemctl is-active -q ping-instances.service; then + systemctl -q stop ping-instances.service fi + NEXTID=$(pvesh get /cluster/nextid) + timezone=$(cat /etc/timezone) + header_info + while true; do - case $CHOICE in - 1) - header_info - echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME${CL}" - VERBOSE="no" - METHOD="default" - base_settings "$VERBOSE" - echo_default - break - ;; - 2) - header_info - echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME (${VERBOSE_CROPPED}Verbose)${CL}" - VERBOSE="yes" - METHOD="default" - base_settings "$VERBOSE" - echo_default - break - ;; - 3) - header_info - echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" - METHOD="advanced" - base_settings - advanced_settings - break - ;; - 4) - header_info - echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" - METHOD="advanced" - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/config-file.func) - config_file - break - ;; + CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SETTINGS" --menu "Choose an option:" \ + 20 60 7 \ + "1" "Default Settings" \ + "2" "Default Settings (with verbose)" \ + "3" "Advanced Settings" \ + "4" "Use Config File" \ + "5" "Manage Default Storage" \ + "6" "Diagnostic Settings" \ + "7" "Exit" --nocancel --default-item "1" 3>&1 1>&2 2>&3) - 5) - manage_default_storage - ;; - 6) - if [[ $DIAGNOSTICS == "yes" ]]; then - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ - --yes-button "No" --no-button "Back"; then - DIAGNOSTICS="no" - sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 + if [ $? -ne 0 ]; then + echo -e "${CROSS}${RD} Menu canceled. Exiting.${CL}" + exit 0 fi - else - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ - --yes-button "Yes" --no-button "Back"; then - DIAGNOSTICS="yes" - sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 - fi - fi - ;; - 7) - echo -e "${CROSS}${RD}Exiting.${CL}" - exit 0 - ;; - *) - echo -e "${CROSS}${RD}Invalid option, please try again.${CL}" - ;; - esac - done + + case $CHOICE in + 1) + header_info + echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME${CL}" + VERBOSE="no" + METHOD="default" + base_settings "$VERBOSE" + echo_default + break + ;; + 2) + header_info + echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME (${VERBOSE_CROPPED}Verbose)${CL}" + VERBOSE="yes" + METHOD="default" + base_settings "$VERBOSE" + echo_default + break + ;; + 3) + header_info + echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" + METHOD="advanced" + base_settings + advanced_settings + break + ;; + 4) + header_info + echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" + METHOD="advanced" + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/config-file.func) + config_file + break + ;; + + 5) + manage_default_storage + ;; + 6) + if [[ $DIAGNOSTICS == "yes" ]]; then + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ + --yes-button "No" --no-button "Back"; then + DIAGNOSTICS="no" + sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 + fi + else + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ + --yes-button "Yes" --no-button "Back"; then + DIAGNOSTICS="yes" + sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 + fi + fi + ;; + 7) + echo -e "${CROSS}${RD}Exiting.${CL}" + exit 0 + ;; + *) + echo -e "${CROSS}${RD}Invalid option, please try again.${CL}" + ;; + esac + done } check_container_resources() { - # Check actual RAM & Cores - current_ram=$(free -m | awk 'NR==2{print $2}') - current_cpu=$(nproc) + # Check actual RAM & Cores + current_ram=$(free -m | awk 'NR==2{print $2}') + current_cpu=$(nproc) - # Check whether the current RAM is less than the required RAM or the CPU cores are less than required - if [[ "$current_ram" -lt "$var_ram" ]] || [[ "$current_cpu" -lt "$var_cpu" ]]; then - echo -e "\n${INFO}${HOLD} ${GN}Required: ${var_cpu} CPU, ${var_ram}MB RAM ${CL}| ${RD}Current: ${current_cpu} CPU, ${current_ram}MB RAM${CL}" - echo -e "${YWB}Please ensure that the ${APP} LXC is configured with at least ${var_cpu} vCPU and ${var_ram} MB RAM for the build process.${CL}\n" - echo -ne "${INFO}${HOLD} May cause data loss! ${INFO} Continue update with under-provisioned LXC? " - read -r prompt - # Check if the input is 'yes', otherwise exit with status 1 - if [[ ! ${prompt,,} =~ ^(yes)$ ]]; then - echo -e "${CROSS}${HOLD} ${YWB}Exiting based on user input.${CL}" - exit 1 + # Check whether the current RAM is less than the required RAM or the CPU cores are less than required + if [[ "$current_ram" -lt "$var_ram" ]] || [[ "$current_cpu" -lt "$var_cpu" ]]; then + echo -e "\n${INFO}${HOLD} ${GN}Required: ${var_cpu} CPU, ${var_ram}MB RAM ${CL}| ${RD}Current: ${current_cpu} CPU, ${current_ram}MB RAM${CL}" + echo -e "${YWB}Please ensure that the ${APP} LXC is configured with at least ${var_cpu} vCPU and ${var_ram} MB RAM for the build process.${CL}\n" + echo -ne "${INFO}${HOLD} May cause data loss! ${INFO} Continue update with under-provisioned LXC? " + read -r prompt + # Check if the input is 'yes', otherwise exit with status 1 + if [[ ! ${prompt,,} =~ ^(yes)$ ]]; then + echo -e "${CROSS}${HOLD} ${YWB}Exiting based on user input.${CL}" + exit 1 + fi + else + echo -e "" fi - else - echo -e "" - fi } check_container_storage() { - # Check if the /boot partition is more than 80% full - total_size=$(df /boot --output=size | tail -n 1) - local used_size=$(df /boot --output=used | tail -n 1) - usage=$((100 * used_size / total_size)) - if ((usage > 80)); then - # Prompt the user for confirmation to continue - echo -e "${INFO}${HOLD} ${YWB}Warning: Storage is dangerously low (${usage}%).${CL}" - echo -ne "Continue anyway? " - read -r prompt - # Check if the input is 'y' or 'yes', otherwise exit with status 1 - if [[ ! ${prompt,,} =~ ^(y|yes)$ ]]; then - echo -e "${CROSS}${HOLD}${YWB}Exiting based on user input.${CL}" - exit 1 + # Check if the /boot partition is more than 80% full + total_size=$(df /boot --output=size | tail -n 1) + local used_size=$(df /boot --output=used | tail -n 1) + usage=$((100 * used_size / total_size)) + if ((usage > 80)); then + # Prompt the user for confirmation to continue + echo -e "${INFO}${HOLD} ${YWB}Warning: Storage is dangerously low (${usage}%).${CL}" + echo -ne "Continue anyway? " + read -r prompt + # Check if the input is 'y' or 'yes', otherwise exit with status 1 + if [[ ! ${prompt,,} =~ ^(y|yes)$ ]]; then + echo -e "${CROSS}${HOLD}${YWB}Exiting based on user input.${CL}" + exit 1 + fi fi - fi } start() { - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/tools.func) - if command -v pveversion >/dev/null 2>&1; then - install_script - else - CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC Update/Setting" --menu \ - "Support/Update functions for ${APP} LXC. Choose an option:" \ - 12 60 3 \ - "1" "YES (Silent Mode)" \ - "2" "YES (Verbose Mode)" \ - "3" "NO (Cancel Update)" --nocancel --default-item "1" 3>&1 1>&2 2>&3) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/tools.func) + if command -v pveversion >/dev/null 2>&1; then + install_script + else + CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC Update/Setting" --menu \ + "Support/Update functions for ${APP} LXC. Choose an option:" \ + 12 60 3 \ + "1" "YES (Silent Mode)" \ + "2" "YES (Verbose Mode)" \ + "3" "NO (Cancel Update)" --nocancel --default-item "1" 3>&1 1>&2 2>&3) - case "$CHOICE" in - 1) - VERBOSE="no" - set_std_mode - ;; - 2) - VERBOSE="yes" - set_std_mode - ;; - 3) - clear - exit_script - exit - ;; - esac - update_script - fi + case "$CHOICE" in + 1) + VERBOSE="no" + set_std_mode + ;; + 2) + VERBOSE="yes" + set_std_mode + ;; + 3) + clear + exit_script + exit + ;; + esac + update_script + fi } # This function collects user settings and integrates all the collected information. build_container() { - # if [ "$VERBOSE" == "yes" ]; then set -x; fi + # if [ "$VERBOSE" == "yes" ]; then set -x; fi - NET_STRING="-net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU" - case "$IPV6_METHOD" in - auto) NET_STRING="$NET_STRING,ip6=auto" ;; - dhcp) NET_STRING="$NET_STRING,ip6=dhcp" ;; - static) - NET_STRING="$NET_STRING,ip6=$IPV6_ADDR" - [ -n "$IPV6_GATE" ] && NET_STRING="$NET_STRING,gw6=$IPV6_GATE" - ;; - none) ;; - esac + NET_STRING="-net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU" + case "$IPV6_METHOD" in + auto) NET_STRING="$NET_STRING,ip6=auto" ;; + dhcp) NET_STRING="$NET_STRING,ip6=dhcp" ;; + static) + NET_STRING="$NET_STRING,ip6=$IPV6_ADDR" + [ -n "$IPV6_GATE" ] && NET_STRING="$NET_STRING,gw6=$IPV6_GATE" + ;; + none) ;; + esac - if [ "$CT_TYPE" == "1" ]; then - FEATURES="keyctl=1,nesting=1" - else - FEATURES="nesting=1" - fi + if [ "$CT_TYPE" == "1" ]; then + FEATURES="keyctl=1,nesting=1" + else + FEATURES="nesting=1" + fi - if [ "$ENABLE_FUSE" == "yes" ]; then - FEATURES="$FEATURES,fuse=1" - fi + if [ "$ENABLE_FUSE" == "yes" ]; then + FEATURES="$FEATURES,fuse=1" + fi - #if [[ $DIAGNOSTICS == "yes" ]]; then - # post_to_api - #fi + #if [[ $DIAGNOSTICS == "yes" ]]; then + # post_to_api + #fi - TEMP_DIR=$(mktemp -d) - pushd "$TEMP_DIR" >/dev/null - if [ "$var_os" == "alpine" ]; then - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/alpine-install.func)" - else - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/install.func)" - fi - export DIAGNOSTICS="$DIAGNOSTICS" - export RANDOM_UUID="$RANDOM_UUID" - export CACHER="$APT_CACHER" - export CACHER_IP="$APT_CACHER_IP" - export tz="$timezone" - #export DISABLEIPV6="$DISABLEIP6" - export APPLICATION="$APP" - export app="$NSAPP" - export PASSWORD="$PW" - export VERBOSE="$VERBOSE" - export SSH_ROOT="${SSH}" - export SSH_AUTHORIZED_KEY - export CTID="$CT_ID" - export CTTYPE="$CT_TYPE" - export ENABLE_FUSE="$ENABLE_FUSE" - export ENABLE_TUN="$ENABLE_TUN" - export PCT_OSTYPE="$var_os" - export PCT_OSVERSION="$var_version" - export PCT_DISK_SIZE="$DISK_SIZE" - export PCT_OPTIONS=" + TEMP_DIR=$(mktemp -d) + pushd "$TEMP_DIR" >/dev/null + if [ "$var_os" == "alpine" ]; then + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/alpine-install.func)" + else + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/install.func)" + fi + export DIAGNOSTICS="$DIAGNOSTICS" + export RANDOM_UUID="$RANDOM_UUID" + export CACHER="$APT_CACHER" + export CACHER_IP="$APT_CACHER_IP" + export tz="$timezone" + #export DISABLEIPV6="$DISABLEIP6" + export APPLICATION="$APP" + export app="$NSAPP" + export PASSWORD="$PW" + export VERBOSE="$VERBOSE" + export SSH_ROOT="${SSH}" + export SSH_AUTHORIZED_KEY + export CTID="$CT_ID" + export CTTYPE="$CT_TYPE" + export ENABLE_FUSE="$ENABLE_FUSE" + export ENABLE_TUN="$ENABLE_TUN" + export PCT_OSTYPE="$var_os" + export PCT_OSVERSION="$var_version" + export PCT_DISK_SIZE="$DISK_SIZE" + export PCT_OPTIONS=" -features $FEATURES -hostname $HN -tags $TAGS @@ -1191,18 +1191,18 @@ build_container() { -unprivileged $CT_TYPE $PW " - # This executes create_lxc.sh and creates the container and .conf file - CREATE_CMD="bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/create_lxc.sh)\"" - eval "$CREATE_CMD" - RET=$? - if [[ $RET -ne 0 ]]; then - msg_error "in line $LINENO: exit code $RET: while executing command $CREATE_CMD" - exit $RET - fi + # This executes create_lxc.sh and creates the container and .conf file + CREATE_CMD="bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/create_lxc.sh)\"" + eval "$CREATE_CMD" + RET=$? + if [[ $RET -ne 0 ]]; then + msg_error "in line $LINENO: exit code $RET: while executing command $CREATE_CMD" + exit $RET + fi - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - if [ "$CT_TYPE" == "0" ]; then - cat <>"$LXC_CONFIG" + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + if [ "$CT_TYPE" == "0" ]; then + cat <>"$LXC_CONFIG" # USB passthrough lxc.cgroup2.devices.allow: a lxc.cap.drop: @@ -1214,11 +1214,11 @@ lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create= lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF - fi + fi - if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then - cat <>$LXC_CONFIG + if [ "$CT_TYPE" == "0" ]; then + if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then + cat <>$LXC_CONFIG # VAAPI hardware transcoding lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm @@ -1227,72 +1227,72 @@ lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file EOF - fi - else - if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then - if [[ -e "/dev/dri/renderD128" ]]; then - if [[ -e "/dev/dri/card0" ]]; then - cat <>$LXC_CONFIG + fi + else + if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then + if [[ -e "/dev/dri/renderD128" ]]; then + if [[ -e "/dev/dri/card0" ]]; then + cat <>$LXC_CONFIG # VAAPI hardware transcoding dev0: /dev/dri/card0,gid=44 dev1: /dev/dri/renderD128,gid=104 EOF - else - cat <>"$LXC_CONFIG" + else + cat <>"$LXC_CONFIG" # VAAPI hardware transcoding dev0: /dev/dri/card1,gid=44 dev1: /dev/dri/renderD128,gid=104 EOF + fi + fi fi - fi fi - fi - if [ "$ENABLE_TUN" == "yes" ]; then - cat <>"$LXC_CONFIG" + if [ "$ENABLE_TUN" == "yes" ]; then + cat <>"$LXC_CONFIG" lxc.cgroup2.devices.allow: c 10:200 rwm lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file EOF - fi + fi - # This starts the container and executes -install.sh - msg_info "Starting LXC Container" - pct start "$CTID" - msg_ok "Started LXC Container" - msg_info "Customizing LXC Container" - if [ "$var_os" == "alpine" ]; then - sleep 3 - pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories + # This starts the container and executes -install.sh + msg_info "Starting LXC Container" + pct start "$CTID" + msg_ok "Started LXC Container" + msg_info "Customizing LXC Container" + if [ "$var_os" == "alpine" ]; then + sleep 3 + pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories http://dl-cdn.alpinelinux.org/alpine/latest-stable/main http://dl-cdn.alpinelinux.org/alpine/latest-stable/community EOF' - pct exec "$CTID" -- ash -c "apk add bash newt curl openssh nano mc ncurses >/dev/null" - else - sleep 3 - # Set locale and timezone before update - pct exec "$CTID" -- bash -c "sed -i '/$LANG/ s/^# //' /etc/locale.gen" - pct exec "$CTID" -- bash -c "locale_line=\$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print \$1}' | head -n 1) && \ + pct exec "$CTID" -- ash -c "apk add bash newt curl openssh nano mc ncurses >/dev/null" + else + sleep 3 + # Set locale and timezone before update + pct exec "$CTID" -- bash -c "sed -i '/$LANG/ s/^# //' /etc/locale.gen" + pct exec "$CTID" -- bash -c "locale_line=\$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print \$1}' | head -n 1) && \ echo LANG=\$locale_line >/etc/default/locale && \ locale-gen >/dev/null && \ export LANG=\$locale_line" - pct exec "$CTID" -- bash -c "echo $tz >/etc/timezone && ln -sf /usr/share/zoneinfo/$tz /etc/localtime" + pct exec "$CTID" -- bash -c "echo $tz >/etc/timezone && ln -sf /usr/share/zoneinfo/$tz /etc/localtime" - # Install curl - pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" - fi - msg_ok "Customized LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/install/$var_install.sh)" $? + # Install curl + pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" + fi + msg_ok "Customized LXC Container" + lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/install/$var_install.sh)" $? } # This function sets the description of the container. description() { - IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) + IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - # Generate LXC Description - DESCRIPTION=$( - cat < Logo @@ -1320,41 +1320,41 @@ description() { EOF - ) + ) - # Set Description in LXC - pct set "$CTID" -description "$DESCRIPTION" + # Set Description in LXC + pct set "$CTID" -description "$DESCRIPTION" - if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service - fi + if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service + fi - post_update_to_api "done" "none" + post_update_to_api "done" "none" } api_exit_script() { - exit_code=$? - if [ $exit_code -ne 0 ]; then - case $exit_code in - 100) post_update_to_api "failed" "100: Unexpected error in create_lxc.sh" ;; - 101) post_update_to_api "failed" "101: No network connection detected in create_lxc.sh" ;; - 200) post_update_to_api "failed" "200: LXC creation failed in create_lxc.sh" ;; - 201) post_update_to_api "failed" "201: Invalid Storage class in create_lxc.sh" ;; - 202) post_update_to_api "failed" "202: User aborted menu in create_lxc.sh" ;; - 203) post_update_to_api "failed" "203: CTID not set in create_lxc.sh" ;; - 204) post_update_to_api "failed" "204: PCT_OSTYPE not set in create_lxc.sh" ;; - 205) post_update_to_api "failed" "205: CTID cannot be less than 100 in create_lxc.sh" ;; - 206) post_update_to_api "failed" "206: CTID already in use in create_lxc.sh" ;; - 207) post_update_to_api "failed" "207: Template not found in create_lxc.sh" ;; - 208) post_update_to_api "failed" "208: Error downloading template in create_lxc.sh" ;; - 209) post_update_to_api "failed" "209: Container creation failed, but template is intact in create_lxc.sh" ;; - *) post_update_to_api "failed" "Unknown error, exit code: $exit_code in create_lxc.sh" ;; - esac - fi + exit_code=$? + if [ $exit_code -ne 0 ]; then + case $exit_code in + 100) post_update_to_api "failed" "100: Unexpected error in create_lxc.sh" ;; + 101) post_update_to_api "failed" "101: No network connection detected in create_lxc.sh" ;; + 200) post_update_to_api "failed" "200: LXC creation failed in create_lxc.sh" ;; + 201) post_update_to_api "failed" "201: Invalid Storage class in create_lxc.sh" ;; + 202) post_update_to_api "failed" "202: User aborted menu in create_lxc.sh" ;; + 203) post_update_to_api "failed" "203: CTID not set in create_lxc.sh" ;; + 204) post_update_to_api "failed" "204: PCT_OSTYPE not set in create_lxc.sh" ;; + 205) post_update_to_api "failed" "205: CTID cannot be less than 100 in create_lxc.sh" ;; + 206) post_update_to_api "failed" "206: CTID already in use in create_lxc.sh" ;; + 207) post_update_to_api "failed" "207: Template not found in create_lxc.sh" ;; + 208) post_update_to_api "failed" "208: Error downloading template in create_lxc.sh" ;; + 209) post_update_to_api "failed" "209: Container creation failed, but template is intact in create_lxc.sh" ;; + *) post_update_to_api "failed" "Unknown error, exit code: $exit_code in create_lxc.sh" ;; + esac + fi } if command -v pveversion >/dev/null 2>&1; then - trap 'api_exit_script' EXIT + trap 'api_exit_script' EXIT fi trap 'post_update_to_api "failed" "$BASH_COMMAND"' ERR trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT diff --git a/misc/install.func b/misc/install.func index 94ddff89..f745e157 100644 --- a/misc/install.func +++ b/misc/install.func @@ -31,7 +31,7 @@ catch_errors() { # This function handles errors error_handler() { - source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) + source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/api.func) printf "\e[?25h" local exit_code="$?" local line_number="$1" @@ -195,7 +195,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi - echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update + echo "bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/ct/${app}.sh)\"" >/usr/bin/update chmod +x /usr/bin/update if [[ -n "${SSH_AUTHORIZED_KEY}" ]]; then mkdir -p /root/.ssh From 80cb9b32043b6c69104d0369cff487baff505969 Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 27 Jun 2025 17:36:17 -0700 Subject: [PATCH 016/463] revert build links for prod --- misc/build.func | 22 +++++++++++----------- misc/install.func | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/misc/build.func b/misc/build.func index 351f5830..add337a3 100644 --- a/misc/build.func +++ b/misc/build.func @@ -15,14 +15,14 @@ variables() { CT_TYPE=${var_unprivileged:-$CT_TYPE} } -source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/api.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/api.func) if command -v curl >/dev/null 2>&1; then - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/core.func) + source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/core.func) load_functions #echo "(build.func) Loaded core.func via curl" elif command -v wget >/dev/null 2>&1; then - source <(wget -qO- https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/core.func) + source <(wget -qO- https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/core.func) load_functions #echo "(build.func) Loaded core.func via wget" fi @@ -35,7 +35,7 @@ catch_errors() { # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { - source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/api.func) + source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/api.func) printf "\e[?25h" local exit_code="$?" local line_number="$1" @@ -1017,7 +1017,7 @@ install_script() { header_info echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" METHOD="advanced" - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/config-file.func) + source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/config-file.func) config_file break ;; @@ -1093,7 +1093,7 @@ check_container_storage() { } start() { - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/tools.func) + source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/tools.func) if command -v pveversion >/dev/null 2>&1; then install_script else @@ -1155,9 +1155,9 @@ build_container() { TEMP_DIR=$(mktemp -d) pushd "$TEMP_DIR" >/dev/null if [ "$var_os" == "alpine" ]; then - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/alpine-install.func)" + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/alpine-install.func)" else - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/install.func)" + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/install.func)" fi export DIAGNOSTICS="$DIAGNOSTICS" export RANDOM_UUID="$RANDOM_UUID" @@ -1192,7 +1192,7 @@ build_container() { $PW " # This executes create_lxc.sh and creates the container and .conf file - CREATE_CMD="bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/create_lxc.sh)\"" + CREATE_CMD="bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/create_lxc.sh)\"" eval "$CREATE_CMD" RET=$? if [[ $RET -ne 0 ]]; then @@ -1282,7 +1282,7 @@ EOF' pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" fi msg_ok "Customized LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/install/$var_install.sh)" $? + lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/$var_install.sh)" $? } @@ -1295,7 +1295,7 @@ description() { cat < - Logo + Logo

${APP} LXC

diff --git a/misc/install.func b/misc/install.func index f745e157..a25e0e9f 100644 --- a/misc/install.func +++ b/misc/install.func @@ -10,7 +10,7 @@ if ! command -v curl >/dev/null 2>&1; then apt-get update >/dev/null 2>&1 apt-get install -y curl >/dev/null 2>&1 fi -source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/core.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/core.func) load_functions # This function enables IPv6 if it's not disabled and sets verbose mode @@ -31,7 +31,7 @@ catch_errors() { # This function handles errors error_handler() { - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/api.func) + source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/api.func) printf "\e[?25h" local exit_code="$?" local line_number="$1" From e9888cea08728efa8e43e61437ed703e7bdc00b5 Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 27 Jun 2025 17:39:08 -0700 Subject: [PATCH 017/463] Convert deployment to use python uv. Cleaned up some formatting issues Added jsdelivr cdn link for logo. --- ct/scraparr.sh | 51 +++++++++++------------------- frontend/public/json/scraparr.json | 2 +- install/scraparr-install.sh | 14 ++++---- 3 files changed, 27 insertions(+), 40 deletions(-) diff --git a/ct/scraparr.sh b/ct/scraparr.sh index 5fc2199c..14f5d6eb 100644 --- a/ct/scraparr.sh +++ b/ct/scraparr.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/heads/scraparr-uv-migration/misc/build.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) # Copyright (c) 2021-2025 community-scripts ORG # Author: JasonGreenC # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE @@ -23,46 +23,33 @@ function update_script() { header_info check_container_storage check_container_resources + if [[ ! -d /opt/scraparr/ ]]; then msg_error "No ${APP} Installation Found!" exit fi - msg_info "Stopping Services" - systemctl stop scraparr - msg_ok "Services Stopped" - - export SCRAPARR_VENV_PATH="/opt/scraparr/.venv" - export SCRAPARR_EXPORTER_BIN="${SCRAPARR_VENV_PATH}/bin/scraparr" - - if [[ ! -d "$PVE_VENV_PATH" || ! -x "$PVE_EXPORTER_BIN" ]]; then - PYTHON_VERSION="3.12" setup_uv - msg_info "Migrating to uv/venv" - rm -rf "$PVE_VENV_PATH" - mkdir -p /opt/scraparr - cd /opt/scraparr - $STD uv venv "$PVE_VENV_PATH" - $STD "$PVE_VENV_PATH/bin/python" -m ensurepip --upgrade - $STD "$PVE_VENV_PATH/bin/python" -m pip install --upgrade pip - $STD "$PVE_VENV_PATH/bin/python" -m pip install prometheus-pve-exporter - msg_ok "Migrated to uv/venv" - else - msg_info "Updating Prometheus Proxmox VE Exporter" - PYTHON_VERSION="3.12" setup_uv - $STD "$PVE_VENV_PATH/bin/python" -m pip install --upgrade prometheus-pve-exporter - msg_ok "Updated Prometheus Proxmox VE Exporter" - fi RELEASE=$(curl -fsSL https://api.github.com/repos/thecfu/scraparr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') - if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + if [[ ! -f "${HOME}/.scrappar" ]] || [[ "${RELEASE}" != "$(cat "${HOME}"/.scrappar)" ]]; then + msg_info "Stopping Services" + systemctl stop scraparr + msg_ok "Services Stopped" - msg_info "Updating ${APP} to v${RELEASE}" - fetch_and_deploy_gh_release "scrappar" "thecfu/scraparr" - pip -q install -r /opt/scrappar/src/scrappar/requirements.txt --root-user-action=ignore - msg_ok "Updated ${APP}" + PYTHON_VERSION="3.12" setup_uv + fetch_and_deploy_gh_release "scrappar" "thecfu/scraparr" "tarball" "latest" "/opt/scraparr" - msg_info "Starting Service" + msg_info "Updating ${APP} to ${RELEASE}" + cd /opt/scraparr || exit + $STD uv venv /opt/scraparr/.venv + $STD /opt/scraparr/.venv/bin/python -m ensurepip --upgrade + $STD /opt/scraparr/.venv/bin/python -m pip install --upgrade pip + $STD /opt/scraparr/.venv/bin/python -m pip install -r /opt/scraparr/src/scraparr/requirements.txt + chmod -R 755 /opt/scraparr + msg_ok "Updated ${APP} to v${RELEASE}" + + msg_info "Starting Services" systemctl start scraparr - msg_ok "Started Service" + msg_ok "Services Started" else msg_ok "No update required. ${APP} is already at v${RELEASE}" fi diff --git a/frontend/public/json/scraparr.json b/frontend/public/json/scraparr.json index 690e1919..731618e3 100644 --- a/frontend/public/json/scraparr.json +++ b/frontend/public/json/scraparr.json @@ -11,7 +11,7 @@ "interface_port": 7100, "documentation": "https://github.com/thecfu/scraparr/blob/main/README.md", "website": "https://github.com/thecfu/scraparr", - "logo": "https://github.com/thecfu/scraparr/raw/main/.github/assets/logos/scraparr_logo.svg", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/scraparr-dark.svg", "config_path": "/scraparr/config/config.yaml", "description": "Scraparr is a Prometheus exporter for the *arr suite (Sonarr, Radarr, Lidarr, etc.). It provides metrics that can be scraped by Prometheus to monitor and visualize the health and performance of your *arr applications.", "install_methods": [ diff --git a/install/scraparr-install.sh b/install/scraparr-install.sh index 65eb49ae..4eafe0a6 100644 --- a/install/scraparr-install.sh +++ b/install/scraparr-install.sh @@ -13,11 +13,10 @@ setting_up_container network_check update_os -PYTHON_VERSION="3.12" setup_uv - msg_info "Installing Scraparr" -fetch_and_deploy_gh_release "scrappar" "thecfu/scraparr" -cd /opt/scraparr +PYTHON_VERSION="3.12" setup_uv +fetch_and_deploy_gh_release "scrappar" "thecfu/scraparr" "tarball" "latest" "/opt/scraparr" +cd /opt/scraparr || exit $STD uv venv /opt/scraparr/.venv $STD /opt/scraparr/.venv/bin/python -m ensurepip --upgrade $STD /opt/scraparr/.venv/bin/python -m pip install --upgrade pip @@ -34,14 +33,15 @@ cat </etc/systemd/system/scraparr.service Description=Scraparr Wants=network-online.target After=network.target + [Service] Type=simple -ExecStart=/opt/scraparr/.venv/bin/python -m /opt/scraparr/src/scraparr/scraparr -User=root +WorkingDirectory=/opt/scraparr/src +ExecStart=/opt/scraparr/.venv/bin/python -m scraparr.scraparr Restart=always + [Install] WantedBy=multi-user.target - EOF systemctl daemon-reload systemctl enable -q --now scraparr From 5e5f22f8a7b44363b332e9e845e6722711ca0526 Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 27 Jun 2025 17:42:38 -0700 Subject: [PATCH 018/463] Added completation message --- ct/scraparr.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/scraparr.sh b/ct/scraparr.sh index 14f5d6eb..b7eeee7e 100644 --- a/ct/scraparr.sh +++ b/ct/scraparr.sh @@ -60,6 +60,7 @@ 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}:7100${CL}" From fbef07a96243de0e7da7c928d1443e40a262f7b3 Mon Sep 17 00:00:00 2001 From: Jason Green Date: Sat, 28 Jun 2025 12:23:06 -0700 Subject: [PATCH 019/463] removed modified build files --- misc/build.func | 1978 ++++++++++++++++++++++----------------------- misc/install.func | 276 +++---- 2 files changed, 1127 insertions(+), 1127 deletions(-) diff --git a/misc/build.func b/misc/build.func index add337a3..b75e5b38 100644 --- a/misc/build.func +++ b/misc/build.func @@ -5,329 +5,329 @@ # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE variables() { - NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. - var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. - INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. - PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase - DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call. - METHOD="default" # sets the METHOD variable to "default", used for the API call. - RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable. - CT_TYPE=${var_unprivileged:-$CT_TYPE} + NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. + var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. + INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. + PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase + DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call. + METHOD="default" # sets the METHOD variable to "default", used for the API call. + RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable. + CT_TYPE=${var_unprivileged:-$CT_TYPE} } -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/api.func) +source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) if command -v curl >/dev/null 2>&1; then - source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/core.func) - load_functions - #echo "(build.func) Loaded core.func via curl" + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) + load_functions + #echo "(build.func) Loaded core.func via curl" elif command -v wget >/dev/null 2>&1; then - source <(wget -qO- https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/core.func) - load_functions - #echo "(build.func) Loaded core.func via wget" + source <(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) + load_functions + #echo "(build.func) Loaded core.func via wget" fi # This function enables error handling in the script by setting options and defining a trap for the ERR signal. catch_errors() { - set -Eeo pipefail - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + set -Eeo pipefail + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { - source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/api.func) - printf "\e[?25h" - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - post_update_to_api "failed" "${command}" - echo -e "\n$error_message\n" + source /dev/stdin <<<$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) + printf "\e[?25h" + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + post_update_to_api "failed" "${command}" + echo -e "\n$error_message\n" - if [[ -n "$CT_ID" ]]; then - read -p "Remove this Container? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - pct stop "$CT_ID" &>/dev/null - pct destroy "$CT_ID" &>/dev/null - msg_ok "Removed this Container" - fi + if [[ -n "$CT_ID" ]]; then + read -p "Remove this Container? " prompt + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + pct stop "$CT_ID" &>/dev/null + pct destroy "$CT_ID" &>/dev/null + msg_ok "Removed this Container" fi + fi } # Check if the shell is using bash shell_check() { - if [[ "$(basename "$SHELL")" != "bash" ]]; then - clear - msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." - echo -e "\nExiting..." - sleep 2 - exit - fi + if [[ "$(basename "$SHELL")" != "bash" ]]; then + clear + msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." + echo -e "\nExiting..." + sleep 2 + exit + fi } # Run as root only root_check() { - if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then - clear - msg_error "Please run this script as root." - echo -e "\nExiting..." - sleep 2 - exit - fi + if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit + fi } # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { - if ! pveversion | grep -Eq "pve-manager/8\.[0-4](\.[0-9]+)*"; then - msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported" - echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." - echo -e "Exiting..." - sleep 2 - exit - fi + if ! pveversion | grep -Eq "pve-manager/8\.[0-4](\.[0-9]+)*"; then + msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported" + echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." + echo -e "Exiting..." + sleep 2 + exit + fi } # When a node is running tens of containers, it's possible to exceed the kernel's cryptographic key storage allocations. # These are tuneable, so verify if the currently deployment is approaching the limits, advise the user on how to tune the limits, and exit the script. # https://cleveruptime.com/docs/files/proc-key-users | https://docs.kernel.org/security/keys/core.html maxkeys_check() { - # Read kernel parameters - per_user_maxkeys=$(cat /proc/sys/kernel/keys/maxkeys 2>/dev/null || echo 0) - per_user_maxbytes=$(cat /proc/sys/kernel/keys/maxbytes 2>/dev/null || echo 0) + # Read kernel parameters + per_user_maxkeys=$(cat /proc/sys/kernel/keys/maxkeys 2>/dev/null || echo 0) + per_user_maxbytes=$(cat /proc/sys/kernel/keys/maxbytes 2>/dev/null || echo 0) - # Exit if kernel parameters are unavailable - if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then - echo -e "${CROSS}${RD} Error: Unable to read kernel parameters. Ensure proper permissions.${CL}" - exit 1 - fi + # Exit if kernel parameters are unavailable + if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then + echo -e "${CROSS}${RD} Error: Unable to read kernel parameters. Ensure proper permissions.${CL}" + exit 1 + fi - # Fetch key usage for user ID 100000 (typical for containers) - used_lxc_keys=$(awk '/100000:/ {print $2}' /proc/key-users 2>/dev/null || echo 0) - used_lxc_bytes=$(awk '/100000:/ {split($5, a, "/"); print a[1]}' /proc/key-users 2>/dev/null || echo 0) + # Fetch key usage for user ID 100000 (typical for containers) + used_lxc_keys=$(awk '/100000:/ {print $2}' /proc/key-users 2>/dev/null || echo 0) + used_lxc_bytes=$(awk '/100000:/ {split($5, a, "/"); print a[1]}' /proc/key-users 2>/dev/null || echo 0) - # Calculate thresholds and suggested new limits - threshold_keys=$((per_user_maxkeys - 100)) - threshold_bytes=$((per_user_maxbytes - 1000)) - new_limit_keys=$((per_user_maxkeys * 2)) - new_limit_bytes=$((per_user_maxbytes * 2)) + # Calculate thresholds and suggested new limits + threshold_keys=$((per_user_maxkeys - 100)) + threshold_bytes=$((per_user_maxbytes - 1000)) + new_limit_keys=$((per_user_maxkeys * 2)) + new_limit_bytes=$((per_user_maxbytes * 2)) - # Check if key or byte usage is near limits - failure=0 - if [[ "$used_lxc_keys" -gt "$threshold_keys" ]]; then - echo -e "${CROSS}${RD} Warning: Key usage is near the limit (${used_lxc_keys}/${per_user_maxkeys}).${CL}" - echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxkeys=${new_limit_keys}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." - failure=1 - fi - if [[ "$used_lxc_bytes" -gt "$threshold_bytes" ]]; then - echo -e "${CROSS}${RD} Warning: Key byte usage is near the limit (${used_lxc_bytes}/${per_user_maxbytes}).${CL}" - echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxbytes=${new_limit_bytes}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." - failure=1 - fi + # Check if key or byte usage is near limits + failure=0 + if [[ "$used_lxc_keys" -gt "$threshold_keys" ]]; then + echo -e "${CROSS}${RD} Warning: Key usage is near the limit (${used_lxc_keys}/${per_user_maxkeys}).${CL}" + echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxkeys=${new_limit_keys}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." + failure=1 + fi + if [[ "$used_lxc_bytes" -gt "$threshold_bytes" ]]; then + echo -e "${CROSS}${RD} Warning: Key byte usage is near the limit (${used_lxc_bytes}/${per_user_maxbytes}).${CL}" + echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxbytes=${new_limit_bytes}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." + failure=1 + fi - # Provide next steps if issues are detected - if [[ "$failure" -eq 1 ]]; then - echo -e "${INFO} To apply changes, run: ${BOLD}service procps force-reload${CL}" - exit 1 - fi + # Provide next steps if issues are detected + if [[ "$failure" -eq 1 ]]; then + echo -e "${INFO} To apply changes, run: ${BOLD}service procps force-reload${CL}" + exit 1 + fi - echo -e "${CM}${GN} All kernel key limits are within safe thresholds.${CL}" + echo -e "${CM}${GN} All kernel key limits are within safe thresholds.${CL}" } # This function checks the system architecture and exits if it's not "amd64". arch_check() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n" - echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" - echo -e "Exiting..." - sleep 2 - exit - fi + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n" + echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" + echo -e "Exiting..." + sleep 2 + exit + fi } # Function to get the current IP address based on the distribution get_current_ip() { - if [ -f /etc/os-release ]; then - # Check for Debian/Ubuntu (uses hostname -I) - if grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then - CURRENT_IP=$(hostname -I | awk '{print $1}') - # Check for Alpine (uses ip command) - elif grep -q 'ID=alpine' /etc/os-release; then - CURRENT_IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) - else - CURRENT_IP="Unknown" - fi + if [ -f /etc/os-release ]; then + # Check for Debian/Ubuntu (uses hostname -I) + if grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then + CURRENT_IP=$(hostname -I | awk '{print $1}') + # Check for Alpine (uses ip command) + elif grep -q 'ID=alpine' /etc/os-release; then + CURRENT_IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) + else + CURRENT_IP="Unknown" fi - echo "$CURRENT_IP" + fi + echo "$CURRENT_IP" } # Function to update the IP address in the MOTD file update_motd_ip() { - MOTD_FILE="/etc/motd" + MOTD_FILE="/etc/motd" - if [ -f "$MOTD_FILE" ]; then - # Remove existing IP Address lines to prevent duplication - sed -i '/IP Address:/d' "$MOTD_FILE" + if [ -f "$MOTD_FILE" ]; then + # Remove existing IP Address lines to prevent duplication + sed -i '/IP Address:/d' "$MOTD_FILE" - IP=$(get_current_ip) - # Add the new IP address - echo -e "${TAB}${NETWORK}${YW} IP Address: ${GN}${IP}${CL}" >>"$MOTD_FILE" - fi + IP=$(get_current_ip) + # Add the new IP address + echo -e "${TAB}${NETWORK}${YW} IP Address: ${GN}${IP}${CL}" >>"$MOTD_FILE" + fi } # This function checks if the script is running through SSH and prompts the user to confirm if they want to proceed or exit. ssh_check() { - if [ -n "${SSH_CLIENT:+x}" ]; then - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's advisable to utilize the Proxmox shell rather than SSH, as there may be potential complications with variable retrieval. Proceed using SSH?" 10 72; then - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Proceed using SSH" "You've chosen to proceed using SSH. If any issues arise, please run the script in the Proxmox shell before creating a repository issue." 10 72 - else - clear - echo "Exiting due to SSH usage. Please consider using the Proxmox shell." - exit - fi + if [ -n "${SSH_CLIENT:+x}" ]; then + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's advisable to utilize the Proxmox shell rather than SSH, as there may be potential complications with variable retrieval. Proceed using SSH?" 10 72; then + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Proceed using SSH" "You've chosen to proceed using SSH. If any issues arise, please run the script in the Proxmox shell before creating a repository issue." 10 72 + else + clear + echo "Exiting due to SSH usage. Please consider using the Proxmox shell." + exit fi + fi } select_storage() { - local CLASS=$1 CONTENT CONTENT_LABEL - case $CLASS in - container) - CONTENT='rootdir' - CONTENT_LABEL='Container' - ;; - template) - CONTENT='vztmpl' - CONTENT_LABEL='Template' - ;; - iso) - CONTENT='iso' - CONTENT_LABEL='ISO image' - ;; - images) - CONTENT='images' - CONTENT_LABEL='VM Disk image' - ;; - backup) - CONTENT='backup' - CONTENT_LABEL='Backup' - ;; - snippets) - CONTENT='snippets' - CONTENT_LABEL='Snippets' - ;; - *) - msg_error "Invalid storage class '$CLASS'." - exit 201 - ;; - esac + local CLASS=$1 CONTENT CONTENT_LABEL + case $CLASS in + container) + CONTENT='rootdir' + CONTENT_LABEL='Container' + ;; + template) + CONTENT='vztmpl' + CONTENT_LABEL='Template' + ;; + iso) + CONTENT='iso' + CONTENT_LABEL='ISO image' + ;; + images) + CONTENT='images' + CONTENT_LABEL='VM Disk image' + ;; + backup) + CONTENT='backup' + CONTENT_LABEL='Backup' + ;; + snippets) + CONTENT='snippets' + CONTENT_LABEL='Snippets' + ;; + *) + msg_error "Invalid storage class '$CLASS'." + exit 201 + ;; + esac - command -v whiptail >/dev/null || { - msg_error "whiptail missing." - exit 220 - } - command -v numfmt >/dev/null || { - msg_error "numfmt missing." - exit 221 - } + command -v whiptail >/dev/null || { + msg_error "whiptail missing." + exit 220 + } + command -v numfmt >/dev/null || { + msg_error "numfmt missing." + exit 221 + } - local -a MENU - while read -r line; do - local TAG=$(echo "$line" | awk '{print $1}') - local TYPE=$(echo "$line" | awk '{printf "%-10s", $2}') - local FREE=$(echo "$line" | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf "%9sB", $6}') - MENU+=("$TAG" "Type: $TYPE Free: $FREE" "OFF") - done < <(pvesm status -content "$CONTENT" | awk 'NR>1') + local -a MENU + while read -r line; do + local TAG=$(echo "$line" | awk '{print $1}') + local TYPE=$(echo "$line" | awk '{printf "%-10s", $2}') + local FREE=$(echo "$line" | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf "%9sB", $6}') + MENU+=("$TAG" "Type: $TYPE Free: $FREE" "OFF") + done < <(pvesm status -content "$CONTENT" | awk 'NR>1') - if [ ${#MENU[@]} -eq 0 ]; then - msg_error "No storage found for content type '$CONTENT'." - exit 203 - fi + if [ ${#MENU[@]} -eq 0 ]; then + msg_error "No storage found for content type '$CONTENT'." + exit 203 + fi - if [ $((${#MENU[@]} / 3)) -eq 1 ]; then - echo "${MENU[0]}" - return - fi + if [ $((${#MENU[@]} / 3)) -eq 1 ]; then + echo "${MENU[0]}" + return + fi - local STORAGE - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ - 16 70 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { - msg_error "Storage selection cancelled by user." - exit 202 - } - echo "$STORAGE" + local STORAGE + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ + "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ + 16 70 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { + msg_error "Storage selection cancelled by user." + exit 202 + } + echo "$STORAGE" } manage_default_storage() { - local file="/usr/local/community-scripts/default_storage" - mkdir -p /usr/local/community-scripts + local file="/usr/local/community-scripts/default_storage" + mkdir -p /usr/local/community-scripts - local tmpl=$(select_storage template) - local cont=$(select_storage container) + local tmpl=$(select_storage template) + local cont=$(select_storage container) - cat <"$file" + cat <"$file" TEMPLATE_STORAGE=$tmpl CONTAINER_STORAGE=$cont EOF - msg_ok "Default Storage set: Template=${BL}$tmpl${CL} ${GN}|${CL} Container=${BL}$cont${CL}" - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --msgbox "Default Storage set:\n\nTemplate: $tmpl\nContainer: $cont" 10 58 + msg_ok "Default Storage set: Template=${BL}$tmpl${CL} ${GN}|${CL} Container=${BL}$cont${CL}" + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --msgbox "Default Storage set:\n\nTemplate: $tmpl\nContainer: $cont" 10 58 } base_settings() { - # Default Settings - CT_TYPE="1" - DISK_SIZE="4" - CORE_COUNT="1" - RAM_SIZE="1024" - VERBOSE="${1:-no}" - PW="" - CT_ID=$NEXTID - HN=$NSAPP - BRG="vmbr0" - NET="dhcp" - IPV6_METHOD="none" - IPV6_STATIC="" - GATE="" - APT_CACHER="" - APT_CACHER_IP="" - #DISABLEIP6="no" - MTU="" - SD="" - NS="" - MAC="" - VLAN="" - SSH="no" - SSH_AUTHORIZED_KEY="" - UDHCPC_FIX="" - TAGS="community-script;" - ENABLE_FUSE="${1:-no}" - ENABLE_TUN="${1:-no}" + # Default Settings + CT_TYPE="1" + DISK_SIZE="4" + CORE_COUNT="1" + RAM_SIZE="1024" + VERBOSE="${1:-no}" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + BRG="vmbr0" + NET="dhcp" + IPV6_METHOD="none" + IPV6_STATIC="" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + #DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + SSH_AUTHORIZED_KEY="" + UDHCPC_FIX="" + TAGS="community-script;" + ENABLE_FUSE="${1:-no}" + ENABLE_TUN="${1:-no}" - # Override default settings with variables from ct script - CT_TYPE=${var_unprivileged:-$CT_TYPE} - DISK_SIZE=${var_disk:-$DISK_SIZE} - CORE_COUNT=${var_cpu:-$CORE_COUNT} - RAM_SIZE=${var_ram:-$RAM_SIZE} - VERB=${var_verbose:-$VERBOSE} - TAGS="${TAGS}${var_tags:-}" - ENABLE_FUSE="${var_fuse:-$ENABLE_FUSE}" - ENABLE_TUN="${var_tun:-$ENABLE_TUN}" + # Override default settings with variables from ct script + CT_TYPE=${var_unprivileged:-$CT_TYPE} + DISK_SIZE=${var_disk:-$DISK_SIZE} + CORE_COUNT=${var_cpu:-$CORE_COUNT} + RAM_SIZE=${var_ram:-$RAM_SIZE} + VERB=${var_verbose:-$VERBOSE} + TAGS="${TAGS}${var_tags:-}" + ENABLE_FUSE="${var_fuse:-$ENABLE_FUSE}" + ENABLE_TUN="${var_tun:-$ENABLE_TUN}" - # Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts - if [ -z "$var_os" ]; then - var_os="debian" - fi - if [ -z "$var_version" ]; then - var_version="12" - fi + # Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts + if [ -z "$var_os" ]; then + var_os="debian" + fi + if [ -z "$var_version" ]; then + var_version="12" + fi } write_config() { - mkdir -p /opt/community-scripts - # This function writes the configuration to a file. - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Write configfile" --yesno "Do you want to write the selections to a config file?" 10 60; then - FILEPATH="/opt/community-scripts/${NSAPP}.conf" - if [[ ! -f $FILEPATH ]]; then - cat <"$FILEPATH" + mkdir -p /opt/community-scripts + # This function writes the configuration to a file. + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Write configfile" --yesno "Do you want to write the selections to a config file?" 10 60; then + FILEPATH="/opt/community-scripts/${NSAPP}.conf" + if [[ ! -f $FILEPATH ]]; then + cat <"$FILEPATH" # ${NSAPP} Configuration File # Generated on $(date) @@ -353,12 +353,12 @@ NS="${NS:-none}" NET="${NET}" EOF - echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" - else - echo -e "${INFO}${BOLD}${RD}Configuration file already exists at ${FILEPATH}${CL}" - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Overwrite configfile" --yesno "Do you want to overwrite the existing config file?" 10 60; then - rm -f "$FILEPATH" - cat <"$FILEPATH" + echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" + else + echo -e "${INFO}${BOLD}${RD}Configuration file already exists at ${FILEPATH}${CL}" + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Overwrite configfile" --yesno "Do you want to overwrite the existing config file?" 10 60; then + rm -f "$FILEPATH" + cat <"$FILEPATH" # ${NSAPP} Configuration File # Generated on $(date) @@ -384,516 +384,516 @@ NS="${NS:-none}" NET="${NET}" EOF - echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" - else - echo -e "${INFO}${BOLD}${RD}Configuration file not overwritten${CL}" - fi - fi + echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" + else + echo -e "${INFO}${BOLD}${RD}Configuration file not overwritten${CL}" + fi fi + fi } # This function displays the default values for various settings. echo_default() { - # Convert CT_TYPE to description - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi + # Convert CT_TYPE to description + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi - # Output the selected values with icons - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" - echo -e "${OS}${BOLD}${DGN}Operating System: $var_os | Version: $var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB | ${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT} | ${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - if [ "$VERB" == "yes" ]; then - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}" - fi - echo -e "${CREATING}${BOLD}${BL}Creating a ${APP} LXC using the above default settings${CL}" - echo -e " " + # Output the selected values with icons + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" + echo -e "${OS}${BOLD}${DGN}Operating System: $var_os | Version: $var_version${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB | ${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT} | ${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" + if [ "$VERB" == "yes" ]; then + echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}" + fi + echo -e "${CREATING}${BOLD}${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e " " } # This function is called when the user decides to exit the script. It clears the screen and displays an exit message. exit_script() { - clear - echo -e "\n${CROSS}${RD}User exited script${CL}\n" - exit + clear + echo -e "\n${CROSS}${RD}User exited script${CL}\n" + exit } # This function allows the user to configure advanced settings for the script. advanced_settings() { - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 - # Setting Default Tag for Advanced Settings - TAGS="community-script;${var_tags:-}" - CT_DEFAULT_TYPE="${CT_TYPE}" - CT_TYPE="" - while [ -z "$CT_TYPE" ]; do - if [ "$CT_DEFAULT_TYPE" == "1" ]; then - if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - if [ -n "$CT_TYPE" ]; then - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os | ${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - fi - else - exit_script - fi + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 + # Setting Default Tag for Advanced Settings + TAGS="community-script;${var_tags:-}" + CT_DEFAULT_TYPE="${CT_TYPE}" + CT_TYPE="" + while [ -z "$CT_TYPE" ]; do + if [ "$CT_DEFAULT_TYPE" == "1" ]; then + if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then + if [ -n "$CT_TYPE" ]; then + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os | ${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" fi - if [ "$CT_DEFAULT_TYPE" == "0" ]; then - if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3); then - if [ -n "$CT_TYPE" ]; then - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - fi - else - exit_script - fi - fi - done - - while true; do - if PW1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD (leave blank for automatic login)" 3>&1 1>&2 2>&3); then - # Empty = Autologin - if [[ -z "$PW1" ]]; then - PW="" - PW1="Automatic Login" - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}$PW1${CL}" - break - fi - - # Invalid: contains spaces - if [[ "$PW1" == *" "* ]]; then - whiptail --msgbox "Password cannot contain spaces." 8 58 - continue - fi - - # Invalid: too short - if ((${#PW1} < 5)); then - whiptail --msgbox "Password must be at least 5 characters." 8 58 - continue - fi - - # Confirm password - if PW2=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nVerify Root Password" 9 58 --title "PASSWORD VERIFICATION" 3>&1 1>&2 2>&3); then - if [[ "$PW1" == "$PW2" ]]; then - PW="-password $PW1" - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}********${CL}" - break - else - whiptail --msgbox "Passwords do not match. Please try again." 8 58 - fi - else - exit_script - fi - else - exit_script - fi - done - - if CT_ID=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 "$NEXTID" --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi - else + else exit_script + fi fi - - while true; do - if CT_NAME=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 "$NSAPP" --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo "${CT_NAME,,}" | tr -d ' ') - fi - # Hostname validate (RFC 1123) - if [[ "$HN" =~ ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ ]]; then - echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}" - break - else - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --msgbox "❌ Invalid hostname: '$HN'\n\nOnly lowercase letters, digits and hyphens (-) are allowed.\nUnderscores (_) or other characters are not permitted!" 10 70 - fi - else - exit_script + if [ "$CT_DEFAULT_TYPE" == "0" ]; then + if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3); then + if [ -n "$CT_TYPE" ]; then + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" + echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" fi - done - - while true; do - DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GB" 8 58 "$var_disk" --title "DISK SIZE" 3>&1 1>&2 2>&3) || exit_script - - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - fi - - if [[ "$DISK_SIZE" =~ ^[1-9][0-9]*$ ]]; then - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" - break - else - whiptail --msgbox "Disk size must be a positive integer!" 8 58 - fi - done - - while true; do - CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ - --inputbox "Allocate CPU Cores" 8 58 "$var_cpu" --title "CORE COUNT" 3>&1 1>&2 2>&3) || exit_script - - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - fi - - if [[ "$CORE_COUNT" =~ ^[1-9][0-9]*$ ]]; then - echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}" - break - else - whiptail --msgbox "CPU core count must be a positive integer!" 8 58 - fi - done - - while true; do - RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ - --inputbox "Allocate RAM in MiB" 8 58 "$var_ram" --title "RAM" 3>&1 1>&2 2>&3) || exit_script - - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - fi - - if [[ "$RAM_SIZE" =~ ^[1-9][0-9]*$ ]]; then - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - break - else - whiptail --msgbox "RAM size must be a positive integer!" 8 58 - fi - done - - IFACE_FILEPATH_LIST="/etc/network/interfaces"$'\n'$(find "/etc/network/interfaces.d/" -type f) - BRIDGES="" - OLD_IFS=$IFS - IFS=$'\n' - for iface_filepath in ${IFACE_FILEPATH_LIST}; do - - iface_indexes_tmpfile=$(mktemp -q -u '.iface-XXXX') - (grep -Pn '^\s*iface' "${iface_filepath}" | cut -d':' -f1 && wc -l "${iface_filepath}" | cut -d' ' -f1) | awk 'FNR==1 {line=$0; next} {print line":"$0-1; line=$0}' >"${iface_indexes_tmpfile}" || true - - if [ -f "${iface_indexes_tmpfile}" ]; then - - while read -r pair; do - start=$(echo "${pair}" | cut -d':' -f1) - end=$(echo "${pair}" | cut -d':' -f2) - - if awk "NR >= ${start} && NR <= ${end}" "${iface_filepath}" | grep -qP '^\s*(bridge[-_](ports|stp|fd|vlan-aware|vids)|ovs_type\s+OVSBridge)\b'; then - iface_name=$(sed "${start}q;d" "${iface_filepath}" | awk '{print $2}') - BRIDGES="${iface_name}"$'\n'"${BRIDGES}" - fi - - done <"${iface_indexes_tmpfile}" - rm -f "${iface_indexes_tmpfile}" - fi - - done - IFS=$OLD_IFS - BRIDGES=$(echo "$BRIDGES" | grep -v '^\s*$' | sort | uniq) - if [[ -z "$BRIDGES" ]]; then - BRG="vmbr0" - echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" - else - BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --menu "Select network bridge:" 15 40 6 $(echo "$BRIDGES" | awk '{print $0, "Bridge"}') 3>&1 1>&2 2>&3) - if [[ -z "$BRG" ]]; then - exit_script - else - echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" - fi - fi - - # IPv4 methods: dhcp, static, none - while true; do - IPV4_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --title "IPv4 Address Management" \ - --menu "Select IPv4 Address Assignment Method:" 12 60 2 \ - "dhcp" "Automatic (DHCP, recommended)" \ - "static" "Static (manual entry)" \ - 3>&1 1>&2 2>&3) - - exit_status=$? - if [ $exit_status -ne 0 ]; then - exit_script - fi - - case "$IPV4_METHOD" in - dhcp) - NET="dhcp" - GATE="" - echo -e "${NETWORK}${BOLD}${DGN}IPv4: DHCP${CL}" - break - ;; - static) - # Static: call and validate CIDR address - while true; do - NET=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --inputbox "Enter Static IPv4 CIDR Address (e.g. 192.168.100.50/24)" 8 58 "" \ - --title "IPv4 ADDRESS" 3>&1 1>&2 2>&3) - if [ -z "$NET" ]; then - whiptail --msgbox "IPv4 address must not be empty." 8 58 - continue - elif [[ "$NET" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then - echo -e "${NETWORK}${BOLD}${DGN}IPv4 Address: ${BGN}$NET${CL}" - break - else - whiptail --msgbox "$NET is not a valid IPv4 CIDR address. Please enter a correct value!" 8 58 - fi - done - - # call and validate Gateway - while true; do - GATE1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --inputbox "Enter Gateway IP address for static IPv4" 8 58 "" \ - --title "Gateway IP" 3>&1 1>&2 2>&3) - if [ -z "$GATE1" ]; then - whiptail --msgbox "Gateway IP address cannot be empty." 8 58 - elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then - whiptail --msgbox "Invalid Gateway IP address format." 8 58 - else - GATE=",gw=$GATE1" - echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}$GATE1${CL}" - break - fi - done - break - ;; - esac - done - - # IPv6 Address Management selection - while true; do - IPV6_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --menu \ - "Select IPv6 Address Management Type:" 15 58 4 \ - "auto" "SLAAC/AUTO (recommended, default)" \ - "dhcp" "DHCPv6" \ - "static" "Static (manual entry)" \ - "none" "Disabled" \ - --default-item "auto" 3>&1 1>&2 2>&3) - [ $? -ne 0 ] && exit_script - - case "$IPV6_METHOD" in - auto) - echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}SLAAC/AUTO${CL}" - IPV6_ADDR="" - IPV6_GATE="" - break - ;; - dhcp) - echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}DHCPv6${CL}" - IPV6_ADDR="dhcp" - IPV6_GATE="" - break - ;; - static) - # Ask for static IPv6 address (CIDR notation, e.g., 2001:db8::1234/64) - while true; do - IPV6_ADDR=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ - "Set a static IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 "" \ - --title "IPv6 STATIC ADDRESS" 3>&1 1>&2 2>&3) || exit_script - if [[ "$IPV6_ADDR" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+(/[0-9]{1,3})$ ]]; then - echo -e "${NETWORK}${BOLD}${DGN}IPv6 Address: ${BGN}$IPV6_ADDR${CL}" - break - else - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ - "$IPV6_ADDR is an invalid IPv6 CIDR address. Please enter a valid IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 - fi - done - # Optional: ask for IPv6 gateway for static config - while true; do - IPV6_GATE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ - "Enter IPv6 gateway address (optional, leave blank for none)" 8 58 "" --title "IPv6 GATEWAY" 3>&1 1>&2 2>&3) - if [ -z "$IPV6_GATE" ]; then - IPV6_GATE="" - break - elif [[ "$IPV6_GATE" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+$ ]]; then - break - else - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ - "Invalid IPv6 gateway format." 8 58 - fi - done - break - ;; - none) - echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}Disabled${CL}" - IPV6_ADDR="none" - IPV6_GATE="" - break - ;; - *) - exit_script - ;; - esac - done - - if [ "$var_os" == "alpine" ]; then - APT_CACHER="" - APT_CACHER_IP="" - else - if APT_CACHER_IP=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for none)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then - APT_CACHER="${APT_CACHER_IP:+yes}" - echo -e "${NETWORK}${BOLD}${DGN}APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" - else - exit_script - fi - fi - - # if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - # DISABLEIP6="yes" - # else - # DISABLEIP6="no" - # fi - # echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - - if MTU1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default [The MTU of your selected vmbr, default is 1500])" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$MTU1" ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}" - else + else exit_script + fi fi + done - if SD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z "$SD" ]; then - SX=Host - SD="" + while true; do + if PW1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD (leave blank for automatic login)" 3>&1 1>&2 2>&3); then + # Empty = Autologin + if [[ -z "$PW1" ]]; then + PW="" + PW1="Automatic Login" + echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}$PW1${CL}" + break + fi + + # Invalid: contains spaces + if [[ "$PW1" == *" "* ]]; then + whiptail --msgbox "Password cannot contain spaces." 8 58 + continue + fi + + # Invalid: too short + if ((${#PW1} < 5)); then + whiptail --msgbox "Password must be at least 5 characters." 8 58 + continue + fi + + # Confirm password + if PW2=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nVerify Root Password" 9 58 --title "PASSWORD VERIFICATION" 3>&1 1>&2 2>&3); then + if [[ "$PW1" == "$PW2" ]]; then + PW="-password $PW1" + echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}********${CL}" + break else - SX=$SD - SD="-searchdomain=$SD" + whiptail --msgbox "Passwords do not match. Please try again." 8 58 fi - echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}$SX${CL}" - else + else exit_script + fi + else + exit_script + fi + done + + if CT_ID=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 "$NEXTID" --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi + else + exit_script + fi + + while true; do + if CT_NAME=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 "$NSAPP" --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo "${CT_NAME,,}" | tr -d ' ') + fi + # Hostname validate (RFC 1123) + if [[ "$HN" =~ ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ ]]; then + echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}" + break + else + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --msgbox "❌ Invalid hostname: '$HN'\n\nOnly lowercase letters, digits and hyphens (-) are allowed.\nUnderscores (_) or other characters are not permitted!" 10 70 + fi + else + exit_script + fi + done + + while true; do + DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GB" 8 58 "$var_disk" --title "DISK SIZE" 3>&1 1>&2 2>&3) || exit_script + + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" fi - if NX=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z "$NX" ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" + if [[ "$DISK_SIZE" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" + break + else + whiptail --msgbox "Disk size must be a positive integer!" 8 58 + fi + done + + while true; do + CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ + --inputbox "Allocate CPU Cores" 8 58 "$var_cpu" --title "CORE COUNT" 3>&1 1>&2 2>&3) || exit_script + + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + fi + + if [[ "$CORE_COUNT" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}" + break + else + whiptail --msgbox "CPU core count must be a positive integer!" 8 58 + fi + done + + while true; do + RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ + --inputbox "Allocate RAM in MiB" 8 58 "$var_ram" --title "RAM" 3>&1 1>&2 2>&3) || exit_script + + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + fi + + if [[ "$RAM_SIZE" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" + break + else + whiptail --msgbox "RAM size must be a positive integer!" 8 58 + fi + done + + IFACE_FILEPATH_LIST="/etc/network/interfaces"$'\n'$(find "/etc/network/interfaces.d/" -type f) + BRIDGES="" + OLD_IFS=$IFS + IFS=$'\n' + for iface_filepath in ${IFACE_FILEPATH_LIST}; do + + iface_indexes_tmpfile=$(mktemp -q -u '.iface-XXXX') + (grep -Pn '^\s*iface' "${iface_filepath}" | cut -d':' -f1 && wc -l "${iface_filepath}" | cut -d' ' -f1) | awk 'FNR==1 {line=$0; next} {print line":"$0-1; line=$0}' >"${iface_indexes_tmpfile}" || true + + if [ -f "${iface_indexes_tmpfile}" ]; then + + while read -r pair; do + start=$(echo "${pair}" | cut -d':' -f1) + end=$(echo "${pair}" | cut -d':' -f2) + + if awk "NR >= ${start} && NR <= ${end}" "${iface_filepath}" | grep -qP '^\s*(bridge[-_](ports|stp|fd|vlan-aware|vids)|ovs_type\s+OVSBridge)\b'; then + iface_name=$(sed "${start}q;d" "${iface_filepath}" | awk '{print $2}') + BRIDGES="${iface_name}"$'\n'"${BRIDGES}" fi - echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}$NX${CL}" - else - exit_script + + done <"${iface_indexes_tmpfile}" + rm -f "${iface_indexes_tmpfile}" fi - if [ "$var_os" == "alpine" ] && [ "$NET" == "dhcp" ] && [ "$NX" != "Host" ]; then - UDHCPC_FIX="yes" + done + IFS=$OLD_IFS + BRIDGES=$(echo "$BRIDGES" | grep -v '^\s*$' | sort | uniq) + if [[ -z "$BRIDGES" ]]; then + BRG="vmbr0" + echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" + else + BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --menu "Select network bridge:" 15 40 6 $(echo "$BRIDGES" | awk '{print $0, "Bridge"}') 3>&1 1>&2 2>&3) + if [[ -z "$BRG" ]]; then + exit_script else - UDHCPC_FIX="no" + echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" fi - export UDHCPC_FIX + fi - if MAC1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a MAC Address(leave blank for generated MAC)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z "$MAC1" ]; then - MAC1="Default" - MAC="" + # IPv4 methods: dhcp, static, none + while true; do + IPV4_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --title "IPv4 Address Management" \ + --menu "Select IPv4 Address Assignment Method:" 12 60 2 \ + "dhcp" "Automatic (DHCP, recommended)" \ + "static" "Static (manual entry)" \ + 3>&1 1>&2 2>&3) + + exit_status=$? + if [ $exit_status -ne 0 ]; then + exit_script + fi + + case "$IPV4_METHOD" in + dhcp) + NET="dhcp" + GATE="" + echo -e "${NETWORK}${BOLD}${DGN}IPv4: DHCP${CL}" + break + ;; + static) + # Static: call and validate CIDR address + while true; do + NET=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --inputbox "Enter Static IPv4 CIDR Address (e.g. 192.168.100.50/24)" 8 58 "" \ + --title "IPv4 ADDRESS" 3>&1 1>&2 2>&3) + if [ -z "$NET" ]; then + whiptail --msgbox "IPv4 address must not be empty." 8 58 + continue + elif [[ "$NET" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then + echo -e "${NETWORK}${BOLD}${DGN}IPv4 Address: ${BGN}$NET${CL}" + break else - MAC=",hwaddr=$MAC1" - echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}" + whiptail --msgbox "$NET is not a valid IPv4 CIDR address. Please enter a correct value!" 8 58 fi - else - exit_script - fi + done - if VLAN1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for no VLAN)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z "$VLAN1" ]; then - VLAN1="Default" - VLAN="" + # call and validate Gateway + while true; do + GATE1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --inputbox "Enter Gateway IP address for static IPv4" 8 58 "" \ + --title "Gateway IP" 3>&1 1>&2 2>&3) + if [ -z "$GATE1" ]; then + whiptail --msgbox "Gateway IP address cannot be empty." 8 58 + elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + whiptail --msgbox "Invalid Gateway IP address format." 8 58 else - VLAN=",tag=$VLAN1" + GATE=",gw=$GATE1" + echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}$GATE1${CL}" + break fi - echo -e "${VLANTAG}${BOLD}${DGN}Vlan: ${BGN}$VLAN1${CL}" - else - exit_script - fi + done + break + ;; + esac + done - if ADV_TAGS=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Custom Tags?[If you remove all, there will be no tags!]" 8 58 "${TAGS}" --title "Advanced Tags" 3>&1 1>&2 2>&3); then - if [ -n "${ADV_TAGS}" ]; then - ADV_TAGS=$(echo "$ADV_TAGS" | tr -d '[:space:]') - TAGS="${ADV_TAGS}" + # IPv6 Address Management selection + while true; do + IPV6_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --menu \ + "Select IPv6 Address Management Type:" 15 58 4 \ + "auto" "SLAAC/AUTO (recommended, default)" \ + "dhcp" "DHCPv6" \ + "static" "Static (manual entry)" \ + "none" "Disabled" \ + --default-item "auto" 3>&1 1>&2 2>&3) + [ $? -ne 0 ] && exit_script + + case "$IPV6_METHOD" in + auto) + echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}SLAAC/AUTO${CL}" + IPV6_ADDR="" + IPV6_GATE="" + break + ;; + dhcp) + echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}DHCPv6${CL}" + IPV6_ADDR="dhcp" + IPV6_GATE="" + break + ;; + static) + # Ask for static IPv6 address (CIDR notation, e.g., 2001:db8::1234/64) + while true; do + IPV6_ADDR=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ + "Set a static IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 "" \ + --title "IPv6 STATIC ADDRESS" 3>&1 1>&2 2>&3) || exit_script + if [[ "$IPV6_ADDR" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+(/[0-9]{1,3})$ ]]; then + echo -e "${NETWORK}${BOLD}${DGN}IPv6 Address: ${BGN}$IPV6_ADDR${CL}" + break else - TAGS=";" + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ + "$IPV6_ADDR is an invalid IPv6 CIDR address. Please enter a valid IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 fi - echo -e "${NETWORK}${BOLD}${DGN}Tags: ${BGN}$TAGS${CL}" - else - exit_script - fi - - SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "SSH Authorized key for root (leave empty for none)" 8 58 --title "SSH Key" 3>&1 1>&2 2>&3)" - - if [[ -z "${SSH_AUTHORIZED_KEY}" ]]; then - SSH_AUTHORIZED_KEY="" - fi - - if [[ "$PW" == -password* || -n "$SSH_AUTHORIZED_KEY" ]]; then - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" + done + # Optional: ask for IPv6 gateway for static config + while true; do + IPV6_GATE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ + "Enter IPv6 gateway address (optional, leave blank for none)" 8 58 "" --title "IPv6 GATEWAY" 3>&1 1>&2 2>&3) + if [ -z "$IPV6_GATE" ]; then + IPV6_GATE="" + break + elif [[ "$IPV6_GATE" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+$ ]]; then + break else - SSH="no" + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ + "Invalid IPv6 gateway format." 8 58 fi - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - else - SSH="no" - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - fi + done + break + ;; + none) + echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}Disabled${CL}" + IPV6_ADDR="none" + IPV6_GATE="" + break + ;; + *) + exit_script + ;; + esac + done - # if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "FUSE Support" --yesno "Enable FUSE support?\nRequired for tools like rclone, mergerfs, AppImage, etc." 10 58); then - # ENABLE_FUSE="yes" - # else - # ENABLE_FUSE="no" - # fi - # echo -e "${FUSE}${BOLD}${DGN}Enable FUSE Support: ${BGN}$ENABLE_FUSE${CL}" - - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERBOSE="yes" + if [ "$var_os" == "alpine" ]; then + APT_CACHER="" + APT_CACHER_IP="" + else + if APT_CACHER_IP=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for none)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then + APT_CACHER="${APT_CACHER_IP:+yes}" + echo -e "${NETWORK}${BOLD}${DGN}APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" else - VERBOSE="no" + exit_script fi - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERBOSE${CL}" + fi - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - write_config + # if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + # DISABLEIP6="yes" + # else + # DISABLEIP6="no" + # fi + # echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + + if MTU1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default [The MTU of your selected vmbr, default is 1500])" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$MTU1" ]; then + MTU1="Default" + MTU="" else - clear - header_info - echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" - advanced_settings + MTU=",mtu=$MTU1" fi + echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}" + else + exit_script + fi + + if SD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then + if [ -z "$SD" ]; then + SX=Host + SD="" + else + SX=$SD + SD="-searchdomain=$SD" + fi + echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}$SX${CL}" + else + exit_script + fi + + if NX=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z "$NX" ]; then + NX=Host + NS="" + else + NS="-nameserver=$NX" + fi + echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}$NX${CL}" + else + exit_script + fi + + if [ "$var_os" == "alpine" ] && [ "$NET" == "dhcp" ] && [ "$NX" != "Host" ]; then + UDHCPC_FIX="yes" + else + UDHCPC_FIX="no" + fi + export UDHCPC_FIX + + if MAC1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a MAC Address(leave blank for generated MAC)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z "$MAC1" ]; then + MAC1="Default" + MAC="" + else + MAC=",hwaddr=$MAC1" + echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}" + fi + else + exit_script + fi + + if VLAN1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for no VLAN)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then + if [ -z "$VLAN1" ]; then + VLAN1="Default" + VLAN="" + else + VLAN=",tag=$VLAN1" + fi + echo -e "${VLANTAG}${BOLD}${DGN}Vlan: ${BGN}$VLAN1${CL}" + else + exit_script + fi + + if ADV_TAGS=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Custom Tags?[If you remove all, there will be no tags!]" 8 58 "${TAGS}" --title "Advanced Tags" 3>&1 1>&2 2>&3); then + if [ -n "${ADV_TAGS}" ]; then + ADV_TAGS=$(echo "$ADV_TAGS" | tr -d '[:space:]') + TAGS="${ADV_TAGS}" + else + TAGS=";" + fi + echo -e "${NETWORK}${BOLD}${DGN}Tags: ${BGN}$TAGS${CL}" + else + exit_script + fi + + SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "SSH Authorized key for root (leave empty for none)" 8 58 --title "SSH Key" 3>&1 1>&2 2>&3)" + + if [[ -z "${SSH_AUTHORIZED_KEY}" ]]; then + SSH_AUTHORIZED_KEY="" + fi + + if [[ "$PW" == -password* || -n "$SSH_AUTHORIZED_KEY" ]]; then + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" + else + SSH="no" + fi + echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" + else + SSH="no" + echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" + fi + + # if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "FUSE Support" --yesno "Enable FUSE support?\nRequired for tools like rclone, mergerfs, AppImage, etc." 10 58); then + # ENABLE_FUSE="yes" + # else + # ENABLE_FUSE="no" + # fi + # echo -e "${FUSE}${BOLD}${DGN}Enable FUSE Support: ${BGN}$ENABLE_FUSE${CL}" + + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERBOSE="yes" + else + VERBOSE="no" + fi + echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERBOSE${CL}" + + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + write_config + else + clear + header_info + echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" + advanced_settings + fi } diagnostics_check() { - if ! [ -d "/usr/local/community-scripts" ]; then - mkdir -p /usr/local/community-scripts - fi + if ! [ -d "/usr/local/community-scripts" ]; then + mkdir -p /usr/local/community-scripts + fi - if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then - cat </usr/local/community-scripts/diagnostics + if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then + cat </usr/local/community-scripts/diagnostics DIAGNOSTICS=yes #This file is used to store the diagnostics settings for the Community-Scripts API. @@ -918,9 +918,9 @@ DIAGNOSTICS=yes #"status" #If you have any concerns, please review the source code at /misc/build.func EOF - DIAGNOSTICS="yes" - else - cat </usr/local/community-scripts/diagnostics + DIAGNOSTICS="yes" + else + cat </usr/local/community-scripts/diagnostics DIAGNOSTICS=no #This file is used to store the diagnostics settings for the Community-Scripts API. @@ -945,240 +945,240 @@ DIAGNOSTICS=no #"status" #If you have any concerns, please review the source code at /misc/build.func EOF - DIAGNOSTICS="no" - fi - else - DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' /usr/local/community-scripts/diagnostics) - + DIAGNOSTICS="no" fi + else + DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' /usr/local/community-scripts/diagnostics) + + fi } install_script() { - pve_check - shell_check - root_check - arch_check - ssh_check - maxkeys_check - diagnostics_check + pve_check + shell_check + root_check + arch_check + ssh_check + maxkeys_check + diagnostics_check - if systemctl is-active -q ping-instances.service; then - systemctl -q stop ping-instances.service + if systemctl is-active -q ping-instances.service; then + systemctl -q stop ping-instances.service + fi + NEXTID=$(pvesh get /cluster/nextid) + timezone=$(cat /etc/timezone) + header_info + while true; do + + CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SETTINGS" --menu "Choose an option:" \ + 20 60 7 \ + "1" "Default Settings" \ + "2" "Default Settings (with verbose)" \ + "3" "Advanced Settings" \ + "4" "Use Config File" \ + "5" "Manage Default Storage" \ + "6" "Diagnostic Settings" \ + "7" "Exit" --nocancel --default-item "1" 3>&1 1>&2 2>&3) + + if [ $? -ne 0 ]; then + echo -e "${CROSS}${RD} Menu canceled. Exiting.${CL}" + exit 0 fi - NEXTID=$(pvesh get /cluster/nextid) - timezone=$(cat /etc/timezone) - header_info - while true; do - CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SETTINGS" --menu "Choose an option:" \ - 20 60 7 \ - "1" "Default Settings" \ - "2" "Default Settings (with verbose)" \ - "3" "Advanced Settings" \ - "4" "Use Config File" \ - "5" "Manage Default Storage" \ - "6" "Diagnostic Settings" \ - "7" "Exit" --nocancel --default-item "1" 3>&1 1>&2 2>&3) + case $CHOICE in + 1) + header_info + echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME${CL}" + VERBOSE="no" + METHOD="default" + base_settings "$VERBOSE" + echo_default + break + ;; + 2) + header_info + echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME (${VERBOSE_CROPPED}Verbose)${CL}" + VERBOSE="yes" + METHOD="default" + base_settings "$VERBOSE" + echo_default + break + ;; + 3) + header_info + echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" + METHOD="advanced" + base_settings + advanced_settings + break + ;; + 4) + header_info + echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" + METHOD="advanced" + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/config-file.func) + config_file + break + ;; - if [ $? -ne 0 ]; then - echo -e "${CROSS}${RD} Menu canceled. Exiting.${CL}" - exit 0 + 5) + manage_default_storage + ;; + 6) + if [[ $DIAGNOSTICS == "yes" ]]; then + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ + --yes-button "No" --no-button "Back"; then + DIAGNOSTICS="no" + sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 fi - - case $CHOICE in - 1) - header_info - echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME${CL}" - VERBOSE="no" - METHOD="default" - base_settings "$VERBOSE" - echo_default - break - ;; - 2) - header_info - echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME (${VERBOSE_CROPPED}Verbose)${CL}" - VERBOSE="yes" - METHOD="default" - base_settings "$VERBOSE" - echo_default - break - ;; - 3) - header_info - echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" - METHOD="advanced" - base_settings - advanced_settings - break - ;; - 4) - header_info - echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" - METHOD="advanced" - source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/config-file.func) - config_file - break - ;; - - 5) - manage_default_storage - ;; - 6) - if [[ $DIAGNOSTICS == "yes" ]]; then - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ - --yes-button "No" --no-button "Back"; then - DIAGNOSTICS="no" - sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 - fi - else - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ - --yes-button "Yes" --no-button "Back"; then - DIAGNOSTICS="yes" - sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 - fi - fi - ;; - 7) - echo -e "${CROSS}${RD}Exiting.${CL}" - exit 0 - ;; - *) - echo -e "${CROSS}${RD}Invalid option, please try again.${CL}" - ;; - esac - done + else + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ + --yes-button "Yes" --no-button "Back"; then + DIAGNOSTICS="yes" + sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 + fi + fi + ;; + 7) + echo -e "${CROSS}${RD}Exiting.${CL}" + exit 0 + ;; + *) + echo -e "${CROSS}${RD}Invalid option, please try again.${CL}" + ;; + esac + done } check_container_resources() { - # Check actual RAM & Cores - current_ram=$(free -m | awk 'NR==2{print $2}') - current_cpu=$(nproc) + # Check actual RAM & Cores + current_ram=$(free -m | awk 'NR==2{print $2}') + current_cpu=$(nproc) - # Check whether the current RAM is less than the required RAM or the CPU cores are less than required - if [[ "$current_ram" -lt "$var_ram" ]] || [[ "$current_cpu" -lt "$var_cpu" ]]; then - echo -e "\n${INFO}${HOLD} ${GN}Required: ${var_cpu} CPU, ${var_ram}MB RAM ${CL}| ${RD}Current: ${current_cpu} CPU, ${current_ram}MB RAM${CL}" - echo -e "${YWB}Please ensure that the ${APP} LXC is configured with at least ${var_cpu} vCPU and ${var_ram} MB RAM for the build process.${CL}\n" - echo -ne "${INFO}${HOLD} May cause data loss! ${INFO} Continue update with under-provisioned LXC? " - read -r prompt - # Check if the input is 'yes', otherwise exit with status 1 - if [[ ! ${prompt,,} =~ ^(yes)$ ]]; then - echo -e "${CROSS}${HOLD} ${YWB}Exiting based on user input.${CL}" - exit 1 - fi - else - echo -e "" + # Check whether the current RAM is less than the required RAM or the CPU cores are less than required + if [[ "$current_ram" -lt "$var_ram" ]] || [[ "$current_cpu" -lt "$var_cpu" ]]; then + echo -e "\n${INFO}${HOLD} ${GN}Required: ${var_cpu} CPU, ${var_ram}MB RAM ${CL}| ${RD}Current: ${current_cpu} CPU, ${current_ram}MB RAM${CL}" + echo -e "${YWB}Please ensure that the ${APP} LXC is configured with at least ${var_cpu} vCPU and ${var_ram} MB RAM for the build process.${CL}\n" + echo -ne "${INFO}${HOLD} May cause data loss! ${INFO} Continue update with under-provisioned LXC? " + read -r prompt + # Check if the input is 'yes', otherwise exit with status 1 + if [[ ! ${prompt,,} =~ ^(yes)$ ]]; then + echo -e "${CROSS}${HOLD} ${YWB}Exiting based on user input.${CL}" + exit 1 fi + else + echo -e "" + fi } check_container_storage() { - # Check if the /boot partition is more than 80% full - total_size=$(df /boot --output=size | tail -n 1) - local used_size=$(df /boot --output=used | tail -n 1) - usage=$((100 * used_size / total_size)) - if ((usage > 80)); then - # Prompt the user for confirmation to continue - echo -e "${INFO}${HOLD} ${YWB}Warning: Storage is dangerously low (${usage}%).${CL}" - echo -ne "Continue anyway? " - read -r prompt - # Check if the input is 'y' or 'yes', otherwise exit with status 1 - if [[ ! ${prompt,,} =~ ^(y|yes)$ ]]; then - echo -e "${CROSS}${HOLD}${YWB}Exiting based on user input.${CL}" - exit 1 - fi + # Check if the /boot partition is more than 80% full + total_size=$(df /boot --output=size | tail -n 1) + local used_size=$(df /boot --output=used | tail -n 1) + usage=$((100 * used_size / total_size)) + if ((usage > 80)); then + # Prompt the user for confirmation to continue + echo -e "${INFO}${HOLD} ${YWB}Warning: Storage is dangerously low (${usage}%).${CL}" + echo -ne "Continue anyway? " + read -r prompt + # Check if the input is 'y' or 'yes', otherwise exit with status 1 + if [[ ! ${prompt,,} =~ ^(y|yes)$ ]]; then + echo -e "${CROSS}${HOLD}${YWB}Exiting based on user input.${CL}" + exit 1 fi + fi } start() { - source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/tools.func) - if command -v pveversion >/dev/null 2>&1; then - install_script - else - CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC Update/Setting" --menu \ - "Support/Update functions for ${APP} LXC. Choose an option:" \ - 12 60 3 \ - "1" "YES (Silent Mode)" \ - "2" "YES (Verbose Mode)" \ - "3" "NO (Cancel Update)" --nocancel --default-item "1" 3>&1 1>&2 2>&3) + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) + if command -v pveversion >/dev/null 2>&1; then + install_script + else + CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC Update/Setting" --menu \ + "Support/Update functions for ${APP} LXC. Choose an option:" \ + 12 60 3 \ + "1" "YES (Silent Mode)" \ + "2" "YES (Verbose Mode)" \ + "3" "NO (Cancel Update)" --nocancel --default-item "1" 3>&1 1>&2 2>&3) - case "$CHOICE" in - 1) - VERBOSE="no" - set_std_mode - ;; - 2) - VERBOSE="yes" - set_std_mode - ;; - 3) - clear - exit_script - exit - ;; - esac - update_script - fi + case "$CHOICE" in + 1) + VERBOSE="no" + set_std_mode + ;; + 2) + VERBOSE="yes" + set_std_mode + ;; + 3) + clear + exit_script + exit + ;; + esac + update_script + fi } # This function collects user settings and integrates all the collected information. build_container() { - # if [ "$VERBOSE" == "yes" ]; then set -x; fi + # if [ "$VERBOSE" == "yes" ]; then set -x; fi - NET_STRING="-net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU" - case "$IPV6_METHOD" in - auto) NET_STRING="$NET_STRING,ip6=auto" ;; - dhcp) NET_STRING="$NET_STRING,ip6=dhcp" ;; - static) - NET_STRING="$NET_STRING,ip6=$IPV6_ADDR" - [ -n "$IPV6_GATE" ] && NET_STRING="$NET_STRING,gw6=$IPV6_GATE" - ;; - none) ;; - esac + NET_STRING="-net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU" + case "$IPV6_METHOD" in + auto) NET_STRING="$NET_STRING,ip6=auto" ;; + dhcp) NET_STRING="$NET_STRING,ip6=dhcp" ;; + static) + NET_STRING="$NET_STRING,ip6=$IPV6_ADDR" + [ -n "$IPV6_GATE" ] && NET_STRING="$NET_STRING,gw6=$IPV6_GATE" + ;; + none) ;; + esac - if [ "$CT_TYPE" == "1" ]; then - FEATURES="keyctl=1,nesting=1" - else - FEATURES="nesting=1" - fi + if [ "$CT_TYPE" == "1" ]; then + FEATURES="keyctl=1,nesting=1" + else + FEATURES="nesting=1" + fi - if [ "$ENABLE_FUSE" == "yes" ]; then - FEATURES="$FEATURES,fuse=1" - fi + if [ "$ENABLE_FUSE" == "yes" ]; then + FEATURES="$FEATURES,fuse=1" + fi - #if [[ $DIAGNOSTICS == "yes" ]]; then - # post_to_api - #fi + #if [[ $DIAGNOSTICS == "yes" ]]; then + # post_to_api + #fi - TEMP_DIR=$(mktemp -d) - pushd "$TEMP_DIR" >/dev/null - if [ "$var_os" == "alpine" ]; then - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/alpine-install.func)" - else - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/install.func)" - fi - export DIAGNOSTICS="$DIAGNOSTICS" - export RANDOM_UUID="$RANDOM_UUID" - export CACHER="$APT_CACHER" - export CACHER_IP="$APT_CACHER_IP" - export tz="$timezone" - #export DISABLEIPV6="$DISABLEIP6" - export APPLICATION="$APP" - export app="$NSAPP" - export PASSWORD="$PW" - export VERBOSE="$VERBOSE" - export SSH_ROOT="${SSH}" - export SSH_AUTHORIZED_KEY - export CTID="$CT_ID" - export CTTYPE="$CT_TYPE" - export ENABLE_FUSE="$ENABLE_FUSE" - export ENABLE_TUN="$ENABLE_TUN" - export PCT_OSTYPE="$var_os" - export PCT_OSVERSION="$var_version" - export PCT_DISK_SIZE="$DISK_SIZE" - export PCT_OPTIONS=" + TEMP_DIR=$(mktemp -d) + pushd "$TEMP_DIR" >/dev/null + if [ "$var_os" == "alpine" ]; then + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)" + else + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)" + fi + export DIAGNOSTICS="$DIAGNOSTICS" + export RANDOM_UUID="$RANDOM_UUID" + export CACHER="$APT_CACHER" + export CACHER_IP="$APT_CACHER_IP" + export tz="$timezone" + #export DISABLEIPV6="$DISABLEIP6" + export APPLICATION="$APP" + export app="$NSAPP" + export PASSWORD="$PW" + export VERBOSE="$VERBOSE" + export SSH_ROOT="${SSH}" + export SSH_AUTHORIZED_KEY + export CTID="$CT_ID" + export CTTYPE="$CT_TYPE" + export ENABLE_FUSE="$ENABLE_FUSE" + export ENABLE_TUN="$ENABLE_TUN" + export PCT_OSTYPE="$var_os" + export PCT_OSVERSION="$var_version" + export PCT_DISK_SIZE="$DISK_SIZE" + export PCT_OPTIONS=" -features $FEATURES -hostname $HN -tags $TAGS @@ -1191,18 +1191,18 @@ build_container() { -unprivileged $CT_TYPE $PW " - # This executes create_lxc.sh and creates the container and .conf file - CREATE_CMD="bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/create_lxc.sh)\"" - eval "$CREATE_CMD" - RET=$? - if [[ $RET -ne 0 ]]; then - msg_error "in line $LINENO: exit code $RET: while executing command $CREATE_CMD" - exit $RET - fi + # This executes create_lxc.sh and creates the container and .conf file + CREATE_CMD="bash -c \"\$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)\"" + eval "$CREATE_CMD" + RET=$? + if [[ $RET -ne 0 ]]; then + msg_error "in line $LINENO: exit code $RET: while executing command $CREATE_CMD" + exit $RET + fi - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - if [ "$CT_TYPE" == "0" ]; then - cat <>"$LXC_CONFIG" + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + if [ "$CT_TYPE" == "0" ]; then + cat <>"$LXC_CONFIG" # USB passthrough lxc.cgroup2.devices.allow: a lxc.cap.drop: @@ -1214,11 +1214,11 @@ lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create= lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF - fi + fi - if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then - cat <>$LXC_CONFIG + if [ "$CT_TYPE" == "0" ]; then + if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then + cat <>$LXC_CONFIG # VAAPI hardware transcoding lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm @@ -1227,75 +1227,75 @@ lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file EOF - fi - else - if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then - if [[ -e "/dev/dri/renderD128" ]]; then - if [[ -e "/dev/dri/card0" ]]; then - cat <>$LXC_CONFIG + fi + else + if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then + if [[ -e "/dev/dri/renderD128" ]]; then + if [[ -e "/dev/dri/card0" ]]; then + cat <>$LXC_CONFIG # VAAPI hardware transcoding dev0: /dev/dri/card0,gid=44 dev1: /dev/dri/renderD128,gid=104 EOF - else - cat <>"$LXC_CONFIG" + else + cat <>"$LXC_CONFIG" # VAAPI hardware transcoding dev0: /dev/dri/card1,gid=44 dev1: /dev/dri/renderD128,gid=104 EOF - fi - fi fi + fi fi + fi - if [ "$ENABLE_TUN" == "yes" ]; then - cat <>"$LXC_CONFIG" + if [ "$ENABLE_TUN" == "yes" ]; then + cat <>"$LXC_CONFIG" lxc.cgroup2.devices.allow: c 10:200 rwm lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file EOF - fi + fi - # This starts the container and executes -install.sh - msg_info "Starting LXC Container" - pct start "$CTID" - msg_ok "Started LXC Container" - msg_info "Customizing LXC Container" - if [ "$var_os" == "alpine" ]; then - sleep 3 - pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories + # This starts the container and executes -install.sh + msg_info "Starting LXC Container" + pct start "$CTID" + msg_ok "Started LXC Container" + msg_info "Customizing LXC Container" + if [ "$var_os" == "alpine" ]; then + sleep 3 + pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories http://dl-cdn.alpinelinux.org/alpine/latest-stable/main http://dl-cdn.alpinelinux.org/alpine/latest-stable/community EOF' - pct exec "$CTID" -- ash -c "apk add bash newt curl openssh nano mc ncurses >/dev/null" - else - sleep 3 - # Set locale and timezone before update - pct exec "$CTID" -- bash -c "sed -i '/$LANG/ s/^# //' /etc/locale.gen" - pct exec "$CTID" -- bash -c "locale_line=\$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print \$1}' | head -n 1) && \ + pct exec "$CTID" -- ash -c "apk add bash newt curl openssh nano mc ncurses >/dev/null" + else + sleep 3 + # Set locale and timezone before update + pct exec "$CTID" -- bash -c "sed -i '/$LANG/ s/^# //' /etc/locale.gen" + pct exec "$CTID" -- bash -c "locale_line=\$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print \$1}' | head -n 1) && \ echo LANG=\$locale_line >/etc/default/locale && \ locale-gen >/dev/null && \ export LANG=\$locale_line" - pct exec "$CTID" -- bash -c "echo $tz >/etc/timezone && ln -sf /usr/share/zoneinfo/$tz /etc/localtime" + pct exec "$CTID" -- bash -c "echo $tz >/etc/timezone && ln -sf /usr/share/zoneinfo/$tz /etc/localtime" - # Install curl - pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" - fi - msg_ok "Customized LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/$var_install.sh)" $? + # Install curl + pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" + fi + msg_ok "Customized LXC Container" + lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/install/$var_install.sh)" $? } # This function sets the description of the container. description() { - IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) + IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - # Generate LXC Description - DESCRIPTION=$( - cat < - Logo + Logo

${APP} LXC

@@ -1320,41 +1320,41 @@ description() { EOF - ) + ) - # Set Description in LXC - pct set "$CTID" -description "$DESCRIPTION" + # Set Description in LXC + pct set "$CTID" -description "$DESCRIPTION" - if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service - fi + if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service + fi - post_update_to_api "done" "none" + post_update_to_api "done" "none" } api_exit_script() { - exit_code=$? - if [ $exit_code -ne 0 ]; then - case $exit_code in - 100) post_update_to_api "failed" "100: Unexpected error in create_lxc.sh" ;; - 101) post_update_to_api "failed" "101: No network connection detected in create_lxc.sh" ;; - 200) post_update_to_api "failed" "200: LXC creation failed in create_lxc.sh" ;; - 201) post_update_to_api "failed" "201: Invalid Storage class in create_lxc.sh" ;; - 202) post_update_to_api "failed" "202: User aborted menu in create_lxc.sh" ;; - 203) post_update_to_api "failed" "203: CTID not set in create_lxc.sh" ;; - 204) post_update_to_api "failed" "204: PCT_OSTYPE not set in create_lxc.sh" ;; - 205) post_update_to_api "failed" "205: CTID cannot be less than 100 in create_lxc.sh" ;; - 206) post_update_to_api "failed" "206: CTID already in use in create_lxc.sh" ;; - 207) post_update_to_api "failed" "207: Template not found in create_lxc.sh" ;; - 208) post_update_to_api "failed" "208: Error downloading template in create_lxc.sh" ;; - 209) post_update_to_api "failed" "209: Container creation failed, but template is intact in create_lxc.sh" ;; - *) post_update_to_api "failed" "Unknown error, exit code: $exit_code in create_lxc.sh" ;; - esac - fi + exit_code=$? + if [ $exit_code -ne 0 ]; then + case $exit_code in + 100) post_update_to_api "failed" "100: Unexpected error in create_lxc.sh" ;; + 101) post_update_to_api "failed" "101: No network connection detected in create_lxc.sh" ;; + 200) post_update_to_api "failed" "200: LXC creation failed in create_lxc.sh" ;; + 201) post_update_to_api "failed" "201: Invalid Storage class in create_lxc.sh" ;; + 202) post_update_to_api "failed" "202: User aborted menu in create_lxc.sh" ;; + 203) post_update_to_api "failed" "203: CTID not set in create_lxc.sh" ;; + 204) post_update_to_api "failed" "204: PCT_OSTYPE not set in create_lxc.sh" ;; + 205) post_update_to_api "failed" "205: CTID cannot be less than 100 in create_lxc.sh" ;; + 206) post_update_to_api "failed" "206: CTID already in use in create_lxc.sh" ;; + 207) post_update_to_api "failed" "207: Template not found in create_lxc.sh" ;; + 208) post_update_to_api "failed" "208: Error downloading template in create_lxc.sh" ;; + 209) post_update_to_api "failed" "209: Container creation failed, but template is intact in create_lxc.sh" ;; + *) post_update_to_api "failed" "Unknown error, exit code: $exit_code in create_lxc.sh" ;; + esac + fi } if command -v pveversion >/dev/null 2>&1; then - trap 'api_exit_script' EXIT + trap 'api_exit_script' EXIT fi trap 'post_update_to_api "failed" "$BASH_COMMAND"' ERR trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT diff --git a/misc/install.func b/misc/install.func index a25e0e9f..efc77be5 100644 --- a/misc/install.func +++ b/misc/install.func @@ -6,134 +6,134 @@ # https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE if ! command -v curl >/dev/null 2>&1; then - printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 - apt-get update >/dev/null 2>&1 - apt-get install -y curl >/dev/null 2>&1 + printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 + 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/ProxmoxVED/main/misc/core.func) +source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) load_functions # This function enables IPv6 if it's not disabled and sets verbose mode verb_ip6() { - set_std_mode # Set STD mode based on VERBOSE + set_std_mode # Set STD mode based on VERBOSE - if [ "$DISABLEIPV6" == "yes" ]; then - echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf - $STD sysctl -p - fi + if [ "$DISABLEIPV6" == "yes" ]; then + echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf + $STD sysctl -p + fi } # This function sets error handling options and defines the error_handler function to handle errors catch_errors() { - set -Eeuo pipefail - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + set -Eeuo pipefail + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } # This function handles errors error_handler() { - source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/api.func) - printf "\e[?25h" - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message" + source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) + printf "\e[?25h" + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message" - if [[ "$line_number" -eq 50 ]]; then - echo -e "The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\n" - post_update_to_api "failed" "No error message, script ran in silent mode" - else - post_update_to_api "failed" "${command}" - fi + if [[ "$line_number" -eq 50 ]]; then + echo -e "The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\n" + post_update_to_api "failed" "No error message, script ran in silent mode" + else + post_update_to_api "failed" "${command}" + fi } # This function sets up the Container OS by generating the locale, setting the timezone, and checking the network connection setting_up_container() { - msg_info "Setting up Container OS" - for ((i = RETRY_NUM; i > 0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - done - if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e "${NETWORK}Check Network Settings" - exit 1 + msg_info "Setting up Container OS" + for ((i = RETRY_NUM; i > 0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break fi - rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED - systemctl disable -q --now systemd-networkd-wait-online.service - msg_ok "Set up Container OS" - msg_custom "${CM}" "${GN}" "Network Connected: ${BL}$(hostname -I)" + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + done + if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e "${NETWORK}Check Network Settings" + exit 1 + fi + rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + systemctl disable -q --now systemd-networkd-wait-online.service + msg_ok "Set up Container OS" + msg_custom "${CM}" "${GN}" "Network Connected: ${BL}$(hostname -I)" } # This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected network_check() { - set +e - trap - ERR - ipv4_connected=false - ipv6_connected=false - sleep 1 + set +e + trap - ERR + ipv4_connected=false + ipv6_connected=false + sleep 1 - # Check IPv4 connectivity to Google, Cloudflare & Quad9 DNS servers. - if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then - msg_ok "IPv4 Internet Connected" - ipv4_connected=true + # Check IPv4 connectivity to Google, Cloudflare & Quad9 DNS servers. + if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then + msg_ok "IPv4 Internet Connected" + ipv4_connected=true + else + msg_error "IPv4 Internet Not Connected" + fi + + # Check IPv6 connectivity to Google, Cloudflare & Quad9 DNS servers. + if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null || ping6 -c 1 -W 1 2001:4860:4860::8888 &>/dev/null || ping6 -c 1 -W 1 2620:fe::fe &>/dev/null; then + msg_ok "IPv6 Internet Connected" + ipv6_connected=true + else + msg_error "IPv6 Internet Not Connected" + fi + + # If both IPv4 and IPv6 checks fail, prompt the user + if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then + read -r -p "No Internet detected, would you like to continue anyway? " prompt + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + echo -e "${INFO}${RD}Expect Issues Without Internet${CL}" else - msg_error "IPv4 Internet Not Connected" + echo -e "${NETWORK}Check Network Settings" + exit 1 fi + fi - # Check IPv6 connectivity to Google, Cloudflare & Quad9 DNS servers. - if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null || ping6 -c 1 -W 1 2001:4860:4860::8888 &>/dev/null || ping6 -c 1 -W 1 2620:fe::fe &>/dev/null; then - msg_ok "IPv6 Internet Connected" - ipv6_connected=true + # DNS resolution checks for GitHub-related domains (IPv4 and/or IPv6) + GITHUB_HOSTS=("github.com" "raw.githubusercontent.com" "api.github.com" "git.community-scripts.org") + GITHUB_STATUS="GitHub DNS:" + DNS_FAILED=false + + for HOST in "${GITHUB_HOSTS[@]}"; do + RESOLVEDIP=$(getent hosts "$HOST" | awk '{ print $1 }' | grep -E '(^([0-9]{1,3}\.){3}[0-9]{1,3}$)|(^[a-fA-F0-9:]+$)' | head -n1) + if [[ -z "$RESOLVEDIP" ]]; then + GITHUB_STATUS+="$HOST:($DNSFAIL)" + DNS_FAILED=true else - msg_error "IPv6 Internet Not Connected" + GITHUB_STATUS+=" $HOST:($DNSOK)" fi + done - # If both IPv4 and IPv6 checks fail, prompt the user - if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then - read -r -p "No Internet detected, would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e "${INFO}${RD}Expect Issues Without Internet${CL}" - else - echo -e "${NETWORK}Check Network Settings" - exit 1 - fi - fi + if [[ "$DNS_FAILED" == true ]]; then + fatal "$GITHUB_STATUS" + else + msg_ok "$GITHUB_STATUS" + fi - # DNS resolution checks for GitHub-related domains (IPv4 and/or IPv6) - GITHUB_HOSTS=("github.com" "raw.githubusercontent.com" "api.github.com" "git.community-scripts.org") - GITHUB_STATUS="GitHub DNS:" - DNS_FAILED=false - - for HOST in "${GITHUB_HOSTS[@]}"; do - RESOLVEDIP=$(getent hosts "$HOST" | awk '{ print $1 }' | grep -E '(^([0-9]{1,3}\.){3}[0-9]{1,3}$)|(^[a-fA-F0-9:]+$)' | head -n1) - if [[ -z "$RESOLVEDIP" ]]; then - GITHUB_STATUS+="$HOST:($DNSFAIL)" - DNS_FAILED=true - else - GITHUB_STATUS+=" $HOST:($DNSOK)" - fi - done - - if [[ "$DNS_FAILED" == true ]]; then - fatal "$GITHUB_STATUS" - else - msg_ok "$GITHUB_STATUS" - fi - - set -e - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + set -e + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } # This function updates the Container OS by running apt-get update and upgrade update_os() { - msg_info "Updating Container OS" - if [[ "$CACHER" == "yes" ]]; then - echo "Acquire::http::Proxy-Auto-Detect \"/usr/local/bin/apt-proxy-detect.sh\";" >/etc/apt/apt.conf.d/00aptproxy - cat </usr/local/bin/apt-proxy-detect.sh + msg_info "Updating Container OS" + if [[ "$CACHER" == "yes" ]]; then + echo "Acquire::http::Proxy-Auto-Detect \"/usr/local/bin/apt-proxy-detect.sh\";" >/etc/apt/apt.conf.d/00aptproxy + cat </usr/local/bin/apt-proxy-detect.sh #!/bin/bash if nc -w1 -z "${CACHER_IP}" 3142; then echo -n "http://${CACHER_IP}:3142" @@ -141,66 +141,66 @@ else echo -n "DIRECT" fi EOF - chmod +x /usr/local/bin/apt-proxy-detect.sh - fi - $STD apt-get update - $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade - rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED - msg_ok "Updated Container OS" - source <(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/misc/tools.func) + chmod +x /usr/local/bin/apt-proxy-detect.sh + fi + $STD apt-get update + $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade + rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + msg_ok "Updated Container OS" + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) } # This function modifies the message of the day (motd) and SSH settings motd_ssh() { - grep -qxF "export TERM='xterm-256color'" /root/.bashrc || echo "export TERM='xterm-256color'" >>/root/.bashrc + grep -qxF "export TERM='xterm-256color'" /root/.bashrc || echo "export TERM='xterm-256color'" >>/root/.bashrc - if [ -f "/etc/os-release" ]; then - OS_NAME=$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '"') - OS_VERSION=$(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"') - elif [ -f "/etc/debian_version" ]; then - OS_NAME="Debian" - OS_VERSION=$(cat /etc/debian_version) - fi + if [ -f "/etc/os-release" ]; then + OS_NAME=$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '"') + OS_VERSION=$(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"') + elif [ -f "/etc/debian_version" ]; then + OS_NAME="Debian" + OS_VERSION=$(cat /etc/debian_version) + fi - PROFILE_FILE="/etc/profile.d/00_lxc-details.sh" - echo "echo -e \"\"" >"$PROFILE_FILE" - echo -e "echo -e \"${BOLD}${YW}${APPLICATION} LXC Container - DEV Repository${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${RD}WARNING: This is a DEVELOPMENT version (ProxmoxVED). Do NOT use in production!${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} IP Address: ${GN}\$(hostname -I | awk '{print \$1}')${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} Repository: ${GN}https://github.com/community-scripts/ProxmoxVED${CL}\"" >>"$PROFILE_FILE" - echo "echo \"\"" >>"$PROFILE_FILE" + PROFILE_FILE="/etc/profile.d/00_lxc-details.sh" + echo "echo -e \"\"" >"$PROFILE_FILE" + echo -e "echo -e \"${BOLD}${YW}${APPLICATION} LXC Container - DEV Repository${CL}\"" >>"$PROFILE_FILE" + echo -e "echo -e \"${RD}WARNING: This is a DEVELOPMENT version (ProxmoxVED). Do NOT use in production!${CL}\"" >>"$PROFILE_FILE" + echo -e "echo -e \"${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}\"" >>"$PROFILE_FILE" + echo -e "echo -e \"${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE" + echo -e "echo -e \"${YW} IP Address: ${GN}\$(hostname -I | awk '{print \$1}')${CL}\"" >>"$PROFILE_FILE" + echo -e "echo -e \"${YW} Repository: ${GN}https://github.com/community-scripts/ProxmoxVED${CL}\"" >>"$PROFILE_FILE" + echo "echo \"\"" >>"$PROFILE_FILE" - chmod -x /etc/update-motd.d/* + chmod -x /etc/update-motd.d/* - if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd - fi + if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd + fi } # This function customizes the container by modifying the getty service and enabling auto-login for the root user customize() { - if [[ "$PASSWORD" == "" ]]; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE + if [[ "$PASSWORD" == "" ]]; then + msg_info "Customizing Container" + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" - fi - echo "bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/JasonGreenC/ProxmoxVED/refs/head/scraparr-uv-migration/ct/${app}.sh)\"" >/usr/bin/update - chmod +x /usr/bin/update - if [[ -n "${SSH_AUTHORIZED_KEY}" ]]; then - mkdir -p /root/.ssh - echo "${SSH_AUTHORIZED_KEY}" >/root/.ssh/authorized_keys - chmod 700 /root/.ssh - chmod 600 /root/.ssh/authorized_keys - fi + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" + fi + echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update + chmod +x /usr/bin/update + if [[ -n "${SSH_AUTHORIZED_KEY}" ]]; then + mkdir -p /root/.ssh + echo "${SSH_AUTHORIZED_KEY}" >/root/.ssh/authorized_keys + chmod 700 /root/.ssh + chmod 600 /root/.ssh/authorized_keys + fi } From d5c94b2f16c3b3255d02ada392db8a55f34a69bc Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Sun, 29 Jun 2025 01:49:33 +0000 Subject: [PATCH 020/463] Update versions.json (#645) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 64 ++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 4dae1a1d..4a9e0147 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,24 @@ [ + { + "name": "home-assistant/core", + "version": "2025.6.3", + "date": "2025-06-24T13:00:12Z" + }, + { + "name": "PrivateBin/PrivateBin", + "version": "1.7.7", + "date": "2025-06-28T19:57:56Z" + }, + { + "name": "linkwarden/linkwarden", + "version": "v2.11.2", + "date": "2025-06-28T17:33:38Z" + }, + { + "name": "msgbyte/tianji", + "version": "v1.22.5", + "date": "2025-06-28T16:06:19Z" + }, { "name": "Jackett/Jackett", "version": "v0.22.2075", @@ -34,11 +54,6 @@ "version": "v1.5.0", "date": "2025-06-27T22:04:32Z" }, - { - "name": "linkwarden/linkwarden", - "version": "v2.11.1", - "date": "2025-06-27T21:21:59Z" - }, { "name": "homarr-labs/homarr", "version": "v1.26.0", @@ -49,11 +64,6 @@ "version": "v0.9.4-rc1", "date": "2025-06-27T18:45:33Z" }, - { - "name": "home-assistant/core", - "version": "2025.6.3", - "date": "2025-06-24T13:00:12Z" - }, { "name": "mattermost/mattermost", "version": "preview-v0.1", @@ -184,11 +194,6 @@ "version": "v4.101.2", "date": "2025-06-25T21:18:52Z" }, - { - "name": "msgbyte/tianji", - "version": "v1.22.4", - "date": "2025-06-25T20:46:20Z" - }, { "name": "influxdata/influxdb", "version": "v3.2.0", @@ -271,8 +276,8 @@ }, { "name": "runtipi/runtipi", - "version": "v4.2.1", - "date": "2025-06-03T20:04:28Z" + "version": "nightly", + "date": "2025-06-23T19:10:33Z" }, { "name": "VictoriaMetrics/VictoriaMetrics", @@ -463,5 +468,30 @@ "name": "crowdsecurity/crowdsec", "version": "v1.6.9", "date": "2025-06-17T11:54:50Z" + }, + { + "name": "glpi-project/glpi", + "version": "10.0.18", + "date": "2025-02-12T11:07:02Z" + }, + { + "name": "morpheus65535/bazarr", + "version": "v1.5.2", + "date": "2025-05-11T16:40:55Z" + }, + { + "name": "donaldzou/WGDashboard", + "version": "v4.2.4", + "date": "2025-06-17T05:37:06Z" + }, + { + "name": "webmin/webmin", + "version": "2.402", + "date": "2025-06-17T05:20:42Z" + }, + { + "name": "emqx/emqx", + "version": "e5.9.1-alpha.1", + "date": "2025-06-16T15:34:01Z" } ] From 0058abb9629655c51a6add1e6ff6cae6b95f9b7d Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Sun, 29 Jun 2025 12:36:44 +0000 Subject: [PATCH 021/463] Update versions.json (#646) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 60 +++++++++++++----------------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 4a9e0147..21589da7 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,24 @@ [ + { + "name": "dgtlmoon/changedetection.io", + "version": "0.50.5", + "date": "2025-06-29T08:54:47Z" + }, + { + "name": "emqx/emqx", + "version": "e5.9.1-rc.1", + "date": "2025-06-29T07:27:21Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2084", + "date": "2025-06-29T05:53:38Z" + }, + { + "name": "theonedev/onedev", + "version": "v11.11.2", + "date": "2025-06-29T01:40:39Z" + }, { "name": "home-assistant/core", "version": "2025.6.3", @@ -20,9 +40,9 @@ "date": "2025-06-28T16:06:19Z" }, { - "name": "Jackett/Jackett", - "version": "v0.22.2075", - "date": "2025-06-28T10:16:17Z" + "name": "keycloak/keycloak", + "version": "26.2.5", + "date": "2025-05-28T06:49:43Z" }, { "name": "Luligu/matterbridge", @@ -74,11 +94,6 @@ "version": "version/2025.6.3", "date": "2025-06-27T14:01:06Z" }, - { - "name": "keycloak/keycloak", - "version": "26.2.5", - "date": "2025-05-28T06:49:43Z" - }, { "name": "rclone/rclone", "version": "v1.70.2", @@ -276,8 +291,8 @@ }, { "name": "runtipi/runtipi", - "version": "nightly", - "date": "2025-06-23T19:10:33Z" + "version": "v4.2.1", + "date": "2025-06-03T20:04:28Z" }, { "name": "VictoriaMetrics/VictoriaMetrics", @@ -329,21 +344,11 @@ "version": "v2.0.114", "date": "2025-06-21T11:20:21Z" }, - { - "name": "theonedev/onedev", - "version": "v11.11.1", - "date": "2025-06-21T09:23:39Z" - }, { "name": "pocketbase/pocketbase", "version": "v0.28.4", "date": "2025-06-21T08:29:04Z" }, - { - "name": "dgtlmoon/changedetection.io", - "version": "0.50.4", - "date": "2025-06-21T07:47:02Z" - }, { "name": "go-gitea/gitea", "version": "v1.24.2", @@ -478,20 +483,5 @@ "name": "morpheus65535/bazarr", "version": "v1.5.2", "date": "2025-05-11T16:40:55Z" - }, - { - "name": "donaldzou/WGDashboard", - "version": "v4.2.4", - "date": "2025-06-17T05:37:06Z" - }, - { - "name": "webmin/webmin", - "version": "2.402", - "date": "2025-06-17T05:20:42Z" - }, - { - "name": "emqx/emqx", - "version": "e5.9.1-alpha.1", - "date": "2025-06-16T15:34:01Z" } ] From ea67c681bc7a968c91d00c7b13fedc79a580d38a Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 01:44:33 +0000 Subject: [PATCH 022/463] Update versions.json (#647) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 49 +++++++++++------------------- 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 21589da7..9c49b72a 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,19 @@ [ + { + "name": "rcourtman/Pulse", + "version": "v3.32.0", + "date": "2025-06-25T22:27:01Z" + }, + { + "name": "sysadminsmedia/homebox", + "version": "v0.20.0", + "date": "2025-06-29T18:50:03Z" + }, + { + "name": "firefly-iii/firefly-iii", + "version": "v6.2.19", + "date": "2025-06-28T06:53:45Z" + }, { "name": "dgtlmoon/changedetection.io", "version": "0.50.5", @@ -49,11 +64,6 @@ "version": "3.1.0", "date": "2025-06-28T09:02:38Z" }, - { - "name": "firefly-iii/firefly-iii", - "version": "v6.2.19", - "date": "2025-06-28T06:53:45Z" - }, { "name": "esphome/esphome", "version": "2025.6.2", @@ -194,11 +204,6 @@ "version": "r8.1.2-rc1", "date": "2025-06-25T22:42:04Z" }, - { - "name": "rcourtman/Pulse", - "version": "v3.32.0", - "date": "2025-06-25T22:27:01Z" - }, { "name": "gristlabs/grist-core", "version": "v1.6.1", @@ -291,8 +296,8 @@ }, { "name": "runtipi/runtipi", - "version": "v4.2.1", - "date": "2025-06-03T20:04:28Z" + "version": "nightly", + "date": "2025-06-23T19:10:33Z" }, { "name": "VictoriaMetrics/VictoriaMetrics", @@ -463,25 +468,5 @@ "name": "BookStackApp/BookStack", "version": "v25.05.1", "date": "2025-06-17T14:38:04Z" - }, - { - "name": "cloudflare/cloudflared", - "version": "2025.6.1", - "date": "2025-06-17T12:45:39Z" - }, - { - "name": "crowdsecurity/crowdsec", - "version": "v1.6.9", - "date": "2025-06-17T11:54:50Z" - }, - { - "name": "glpi-project/glpi", - "version": "10.0.18", - "date": "2025-02-12T11:07:02Z" - }, - { - "name": "morpheus65535/bazarr", - "version": "v1.5.2", - "date": "2025-05-11T16:40:55Z" } ] From 3d83015e992699e5c94614ed37058ae353975f4a Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 08:18:11 +0200 Subject: [PATCH 023/463] Update build.func --- misc/build.func | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/misc/build.func b/misc/build.func index b75e5b38..b93b84c5 100644 --- a/misc/build.func +++ b/misc/build.func @@ -333,13 +333,13 @@ write_config() { CT_TYPE="${CT_TYPE}" DISK_SIZE="${DISK_SIZE}" -CORE_COUNT="${DISK_SIZE}" +CORE_COUNT="${CORE_COUNT}" RAM_SIZE="${RAM_SIZE}" HN="${HN}" BRG="${BRG}" APT_CACHER_IP="${APT_CACHER_IP:-none}" DISABLEIP6="${DISABLEIP6}" -PW="${PW:-none}" +PW='${PW:-none}' SSH="${SSH}" SSH_AUTHORIZED_KEY="${SSH_AUTHORIZED_KEY}" VERBOSE="${VERBOSE}" @@ -351,6 +351,7 @@ SD="${SD:-none}" MAC="${MAC:-none}" NS="${NS:-none}" NET="${NET}" +FUSE="${ENABLE_FUSE}" EOF echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" @@ -364,7 +365,7 @@ EOF CT_TYPE="${CT_TYPE}" DISK_SIZE="${DISK_SIZE}" -CORE_COUNT="${DISK_SIZE}" +CORE_COUNT="${CORE_COUNT}" RAM_SIZE="${RAM_SIZE}" HN="${HN}" BRG="${BRG}" @@ -382,6 +383,7 @@ SD="${SD:-none}" MAC="${MAC:-none}" NS="${NS:-none}" NET="${NET}" +FUSE="${ENABLE_FUSE}" EOF echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" @@ -861,12 +863,12 @@ advanced_settings() { echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" fi - # if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "FUSE Support" --yesno "Enable FUSE support?\nRequired for tools like rclone, mergerfs, AppImage, etc." 10 58); then - # ENABLE_FUSE="yes" - # else - # ENABLE_FUSE="no" - # fi - # echo -e "${FUSE}${BOLD}${DGN}Enable FUSE Support: ${BGN}$ENABLE_FUSE${CL}" + if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "FUSE Support" --yesno "Enable FUSE support?\nRequired for tools like rclone, mergerfs, AppImage, etc." 10 58); then + ENABLE_FUSE="yes" + else + ENABLE_FUSE="no" + fi + echo -e "${FUSE}${BOLD}${DGN}Enable FUSE Support: ${BGN}$ENABLE_FUSE${CL}" if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then VERBOSE="yes" @@ -1269,23 +1271,29 @@ EOF' pct exec "$CTID" -- ash -c "apk add bash newt curl openssh nano mc ncurses >/dev/null" else sleep 3 - # Set locale and timezone before update + pct exec "$CTID" -- bash -c "sed -i '/$LANG/ s/^# //' /etc/locale.gen" pct exec "$CTID" -- bash -c "locale_line=\$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print \$1}' | head -n 1) && \ echo LANG=\$locale_line >/etc/default/locale && \ locale-gen >/dev/null && \ export LANG=\$locale_line" - pct exec "$CTID" -- bash -c "echo $tz >/etc/timezone && ln -sf /usr/share/zoneinfo/$tz /etc/localtime" + if pct exec "$CTID" -- test -e "/usr/share/zoneinfo/$tz"; then + pct exec "$CTID" -- bash -c "echo $tz >/etc/timezone && ln -sf /usr/share/zoneinfo/$tz /etc/localtime" + else + msg_info "Skipping timezone setup – zone '$tz' not found in container" + fi + - # Install curl pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" fi msg_ok "Customized LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/install/$var_install.sh)" $? + + lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/"$var_install".sh)" $? } + # This function sets the description of the container. description() { IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) From 3deb4b8350c72e97e1086bee7fbe6259ea090259 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 08:39:17 +0200 Subject: [PATCH 024/463] Update create_lxc.sh --- misc/create_lxc.sh | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 81520d0a..9bf6dd6c 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -107,12 +107,22 @@ function select_storage() { } local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - MENU+=("$TAG" "Type: $TYPE Free: $FREE " "OFF") - done < <(pvesm status -content $CONTENT | awk 'NR>1') + local -A SEEN=() + local MSG_MAX_LENGTH=0 + + while read -r TAG TYPE _ _ _ FREE _; do + [[ -n "$TAG" && -n "$TYPE" ]] || continue + local KEY="${TAG}:${TYPE}" + [[ -z "${SEEN[$KEY]}" ]] || continue + SEEN["$KEY"]=1 + + local TYPE_PADDED=$(printf "%-10s" "$TYPE") + local FREE_FMT=$(numfmt --to=iec --from-unit=K --format %.2f <<<"$FREE")B + local ITEM="Type: $TYPE_PADDED Free: $FREE_FMT" + ((${#ITEM} + 2 > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=$((${#ITEM} + 2)) + + MENU+=("$KEY" "$ITEM" "OFF") + done < <(pvesm status -content "$CONTENT" | awk 'NR>1') if [ ${#MENU[@]} -eq 0 ]; then msg_error "No storage found for content type '$CONTENT'." @@ -120,18 +130,19 @@ function select_storage() { fi if [ $((${#MENU[@]} / 3)) -eq 1 ]; then - printf "%s" "${MENU[0]}" + echo "${MENU[0]%%:*}" return fi local STORAGE STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ - 16 70 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { + 16 $((MSG_MAX_LENGTH + 23)) 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { msg_error "Storage selection cancelled by user." exit 202 } - printf "%s" "$STORAGE" + + echo "${STORAGE%%:*}" } # Test if required variables are set From bb5bd6e29913986d563269f3761841dc07541821 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 08:42:27 +0200 Subject: [PATCH 025/463] Update core.func --- misc/core.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/core.func b/misc/core.func index b4ad2fa5..34bdf230 100644 --- a/misc/core.func +++ b/misc/core.func @@ -434,7 +434,7 @@ msg_info() { MSG_INFO_SHOWN["$msg"]=1 stop_spinner - + echo -e "OS: ${var_os:-}" if [[ "${VERBOSE:-no}" != "no" || "${var_os:-}" == "alpine" || ! -t 2 ]]; then printf "\r\e[2K%s %b\n" "$HOURGLASS" "${YW}${msg}${CL}" >&2 else From 5ff73c5295e40e3cab47304c7d3b4882b1a80293 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 08:45:45 +0200 Subject: [PATCH 026/463] Update build.func --- misc/build.func | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/misc/build.func b/misc/build.func index b93b84c5..f6f8e582 100644 --- a/misc/build.func +++ b/misc/build.func @@ -403,10 +403,13 @@ echo_default() { fi # Output the selected values with icons - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" - echo -e "${OS}${BOLD}${DGN}Operating System: $var_os | Version: $var_version${CL}" + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" + echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB | ${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT} | ${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" + echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" + echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" if [ "$VERB" == "yes" ]; then echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}" fi @@ -1271,7 +1274,7 @@ EOF' pct exec "$CTID" -- ash -c "apk add bash newt curl openssh nano mc ncurses >/dev/null" else sleep 3 - + pct exec "$CTID" -- bash -c "sed -i '/$LANG/ s/^# //' /etc/locale.gen" pct exec "$CTID" -- bash -c "locale_line=\$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print \$1}' | head -n 1) && \ echo LANG=\$locale_line >/etc/default/locale && \ @@ -1284,16 +1287,13 @@ EOF' msg_info "Skipping timezone setup – zone '$tz' not found in container" fi - pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" fi msg_ok "Customized LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/"$var_install".sh)" $? } - # This function sets the description of the container. description() { IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) From 4da9455c5900950a188ff973478c6cff58a94e40 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 08:52:02 +0200 Subject: [PATCH 027/463] Update core.func --- misc/core.func | 243 ++++++++++++++++++++++++++++++------------------- 1 file changed, 147 insertions(+), 96 deletions(-) diff --git a/misc/core.func b/misc/core.func index 34bdf230..6debe3ff 100644 --- a/misc/core.func +++ b/misc/core.func @@ -363,70 +363,70 @@ fatal() { kill -INT $$ } -# Ensure POSIX compatibility across Alpine and Debian/Ubuntu -# === Spinner Start === -# Trap cleanup on various signals -trap 'cleanup_spinner' EXIT INT TERM HUP +# # Ensure POSIX compatibility across Alpine and Debian/Ubuntu +# # === Spinner Start === +# # Trap cleanup on various signals +# trap 'cleanup_spinner' EXIT INT TERM HUP -spinner_frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏') +# spinner_frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏') -# === Spinner Start === -start_spinner() { - local msg="$1" - local spin_i=0 - local interval=0.1 +# # === Spinner Start === +# start_spinner() { +# local msg="$1" +# local spin_i=0 +# local interval=0.1 - stop_spinner - SPINNER_MSG="$msg" - SPINNER_ACTIVE=1 +# stop_spinner +# SPINNER_MSG="$msg" +# SPINNER_ACTIVE=1 - { - while [[ "$SPINNER_ACTIVE" -eq 1 ]]; do - if [[ -t 2 ]]; then - printf "\r\e[2K%s %b" "${TAB}${spinner_frames[spin_i]}${TAB}" "${YW}${SPINNER_MSG}${CL}" >&2 - else - printf "%s...\n" "$SPINNER_MSG" >&2 - break - fi - spin_i=$(((spin_i + 1) % ${#spinner_frames[@]})) - sleep "$interval" - done - } & +# { +# while [[ "$SPINNER_ACTIVE" -eq 1 ]]; do +# if [[ -t 2 ]]; then +# printf "\r\e[2K%s %b" "${TAB}${spinner_frames[spin_i]}${TAB}" "${YW}${SPINNER_MSG}${CL}" >&2 +# else +# printf "%s...\n" "$SPINNER_MSG" >&2 +# break +# fi +# spin_i=$(((spin_i + 1) % ${#spinner_frames[@]})) +# sleep "$interval" +# done +# } & - local pid=$! - if ps -p "$pid" >/dev/null 2>&1; then - SPINNER_PID="$pid" - else - SPINNER_ACTIVE=0 - SPINNER_PID="" - fi -} +# local pid=$! +# if ps -p "$pid" >/dev/null 2>&1; then +# SPINNER_PID="$pid" +# else +# SPINNER_ACTIVE=0 +# SPINNER_PID="" +# fi +# } -# === Spinner Stop === -stop_spinner() { - if [[ "$SPINNER_ACTIVE" -eq 1 && -n "$SPINNER_PID" ]]; then - SPINNER_ACTIVE=0 +# # === Spinner Stop === +# stop_spinner() { +# if [[ "$SPINNER_ACTIVE" -eq 1 && -n "$SPINNER_PID" ]]; then +# SPINNER_ACTIVE=0 - if kill -0 "$SPINNER_PID" 2>/dev/null; then - kill "$SPINNER_PID" 2>/dev/null || true - for _ in $(seq 1 10); do - sleep 0.05 - kill -0 "$SPINNER_PID" 2>/dev/null || break - done - fi +# if kill -0 "$SPINNER_PID" 2>/dev/null; then +# kill "$SPINNER_PID" 2>/dev/null || true +# for _ in $(seq 1 10); do +# sleep 0.05 +# kill -0 "$SPINNER_PID" 2>/dev/null || break +# done +# fi - if [[ "$SPINNER_PID" =~ ^[0-9]+$ ]]; then - ps -p "$SPINNER_PID" -o pid= >/dev/null 2>&1 && wait "$SPINNER_PID" 2>/dev/null || true - fi +# if [[ "$SPINNER_PID" =~ ^[0-9]+$ ]]; then +# ps -p "$SPINNER_PID" -o pid= >/dev/null 2>&1 && wait "$SPINNER_PID" 2>/dev/null || true +# fi - printf "\r\e[2K" >&2 - SPINNER_PID="" - fi -} +# printf "\r\e[2K" >&2 +# SPINNER_PID="" +# fi +# } -cleanup_spinner() { - stop_spinner -} +# cleanup_spinner() { +# stop_spinner +# } msg_info() { local msg="$1" @@ -442,70 +442,121 @@ msg_info() { fi } -msg_ok() { +spinner() { + local chars="/-\|" i=0 + printf "\e[?25l" # Hide cursor + while true; do + printf "\r \e[36m%s\e[0m" "${chars:i++%${#chars}:1}" + sleep 0.1 + done +} + +msg_info() { local msg="$1" - [[ -z "$msg" ]] && return - stop_spinner - printf "\r\e[2K%s %b\n" "$CM" "${GN}${msg}${CL}" >&2 - if declare -p MSG_INFO_SHOWN &>/dev/null && [[ "$(declare -p MSG_INFO_SHOWN 2>/dev/null)" =~ "declare -A" ]]; then - unset MSG_INFO_SHOWN["$msg"] - fi + [[ -z "$msg" || -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return + MSG_INFO_SHOWN["$msg"]=1 + echo -ne " ${HOLD:-} ${YW}${msg} " + spinner & + SPINNER_PID=$! +} + +msg_ok() { + [[ -n "$SPINNER_PID" ]] && kill "$SPINNER_PID" 2>/dev/null + printf "\e[?25h" # Show cursor again + local msg="$1" + echo -e "${BFR:-} ${CM:-✔️} ${GN}${msg}${CL}" + unset MSG_INFO_SHOWN["$msg"] } msg_error() { + [[ -n "$SPINNER_PID" ]] && kill "$SPINNER_PID" 2>/dev/null + printf "\e[?25h" local msg="$1" - [[ -z "$msg" ]] && return - stop_spinner - printf "\r\e[2K%s %b\n" "$CROSS" "${RD}${msg}${CL}" >&2 + echo -e "${BFR:-} ${CROSS:-✖️} ${RD}${msg}${CL}" } msg_warn() { + [[ -n "$SPINNER_PID" ]] && kill "$SPINNER_PID" 2>/dev/null + printf "\e[?25h" local msg="$1" - [[ -z "$msg" ]] && return - stop_spinner - printf "\r\e[2K%s %b\n" "$INFO" "${YWB}${msg}${CL}" >&2 - if declare -p MSG_INFO_SHOWN &>/dev/null && [[ "$(declare -p MSG_INFO_SHOWN 2>/dev/null)" =~ "declare -A" ]]; then - unset MSG_INFO_SHOWN["$msg"] - fi + echo -e "${BFR:-} ${INFO:-ℹ️} ${YWB}${msg}${CL}" + unset MSG_INFO_SHOWN["$msg"] } msg_custom() { local symbol="${1:-"[*]"}" - local color="${2:-"\e[36m"}" # Default: Cyan + local color="${2:-"\e[36m"}" local msg="${3:-}" - [[ -z "$msg" ]] && return - stop_spinner 2>/dev/null || true - printf "\r\e[2K%s %b\n" "$symbol" "${color}${msg}${CL:-\e[0m}" >&2 + [[ -n "$SPINNER_PID" ]] && kill "$SPINNER_PID" 2>/dev/null + printf "\e[?25h" + echo -e "${BFR:-} ${symbol} ${color}${msg}${CL:-\e[0m}" } -msg_progress() { - local current="$1" - local total="$2" - local label="$3" - local width=40 - local filled percent bar empty - local fill_char="#" - local empty_char="-" +# msg_ok() { +# local msg="$1" +# [[ -z "$msg" ]] && return +# stop_spinner +# printf "\r\e[2K%s %b\n" "$CM" "${GN}${msg}${CL}" >&2 +# if declare -p MSG_INFO_SHOWN &>/dev/null && [[ "$(declare -p MSG_INFO_SHOWN 2>/dev/null)" =~ "declare -A" ]]; then +# unset MSG_INFO_SHOWN["$msg"] +# fi +# } - if ! [[ "$current" =~ ^[0-9]+$ ]] || ! [[ "$total" =~ ^[0-9]+$ ]] || [[ "$total" -eq 0 ]]; then - printf "\r\e[2K%s %b\n" "$CROSS" "${RD}Invalid progress input${CL}" >&2 - return - fi +# msg_error() { +# local msg="$1" +# [[ -z "$msg" ]] && return +# stop_spinner +# printf "\r\e[2K%s %b\n" "$CROSS" "${RD}${msg}${CL}" >&2 +# } - percent=$(((current * 100) / total)) - filled=$(((current * width) / total)) - empty=$((width - filled)) +# msg_warn() { +# local msg="$1" +# [[ -z "$msg" ]] && return +# stop_spinner +# printf "\r\e[2K%s %b\n" "$INFO" "${YWB}${msg}${CL}" >&2 +# if declare -p MSG_INFO_SHOWN &>/dev/null && [[ "$(declare -p MSG_INFO_SHOWN 2>/dev/null)" =~ "declare -A" ]]; then +# unset MSG_INFO_SHOWN["$msg"] +# fi +# } - bar=$(printf "%${filled}s" | tr ' ' "$fill_char") - bar+=$(printf "%${empty}s" | tr ' ' "$empty_char") +# msg_custom() { +# local symbol="${1:-"[*]"}" +# local color="${2:-"\e[36m"}" # Default: Cyan +# local msg="${3:-}" - printf "\r\e[2K%s [%s] %3d%% %s" "${TAB}" "$bar" "$percent" "$label" >&2 +# [[ -z "$msg" ]] && return +# stop_spinner 2>/dev/null || true +# printf "\r\e[2K%s %b\n" "$symbol" "${color}${msg}${CL:-\e[0m}" >&2 +# } - if [[ "$current" -eq "$total" ]]; then - printf "\n" >&2 - fi -} +# msg_progress() { +# local current="$1" +# local total="$2" +# local label="$3" +# local width=40 +# local filled percent bar empty +# local fill_char="#" +# local empty_char="-" + +# if ! [[ "$current" =~ ^[0-9]+$ ]] || ! [[ "$total" =~ ^[0-9]+$ ]] || [[ "$total" -eq 0 ]]; then +# printf "\r\e[2K%s %b\n" "$CROSS" "${RD}Invalid progress input${CL}" >&2 +# return +# fi + +# percent=$(((current * 100) / total)) +# filled=$(((current * width) / total)) +# empty=$((width - filled)) + +# bar=$(printf "%${filled}s" | tr ' ' "$fill_char") +# bar+=$(printf "%${empty}s" | tr ' ' "$empty_char") + +# printf "\r\e[2K%s [%s] %3d%% %s" "${TAB}" "$bar" "$percent" "$label" >&2 + +# if [[ "$current" -eq "$total" ]]; then +# printf "\n" >&2 +# fi +# } run_container_safe() { local ct="$1" From 121d05496c1017167d8798e671a9d2d498be785a Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 08:53:05 +0200 Subject: [PATCH 028/463] Update core.func --- misc/core.func | 86 +++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/misc/core.func b/misc/core.func index 6debe3ff..8ff46c38 100644 --- a/misc/core.func +++ b/misc/core.func @@ -20,10 +20,10 @@ if ! declare -f wait_for >/dev/null; then } fi -declare -A MSG_INFO_SHOWN=() -SPINNER_PID="" -SPINNER_ACTIVE=0 -SPINNER_MSG="" +# declare -A MSG_INFO_SHOWN=() +# SPINNER_PID="" +# SPINNER_ACTIVE=0 +# SPINNER_MSG="" # ------------------------------------------------------------------------------ # Loads core utility groups once (colors, formatting, icons, defaults). @@ -47,9 +47,9 @@ load_functions() { # Error & Signal Handling – robust, universal, subshell-safe # ============================================================================ -_stop_spinner_on_error() { - [[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" 2>/dev/null && wait "$SPINNER_PID" 2>/dev/null || true -} +# _stop_spinner_on_error() { +# [[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" 2>/dev/null && wait "$SPINNER_PID" 2>/dev/null || true +# } _tool_error_hint() { local cmd="$1" @@ -89,35 +89,35 @@ _tool_error_hint() { esac } -on_error() { - local code="$?" - local line="${BASH_LINENO[0]:-unknown}" - local cmd="${BASH_COMMAND:-unknown}" +# on_error() { +# local code="$?" +# local line="${BASH_LINENO[0]:-unknown}" +# local cmd="${BASH_COMMAND:-unknown}" - # Signalcode unterdrücken, falls INT/TERM kommt - [[ "$code" == "130" || "$code" == "143" ]] && return +# # Signalcode unterdrücken, falls INT/TERM kommt +# [[ "$code" == "130" || "$code" == "143" ]] && return - _stop_spinner_on_error - msg_error "Script failed at line $line with exit code $code: $cmd" - exit "$code" -} +# _stop_spinner_on_error +# msg_error "Script failed at line $line with exit code $code: $cmd" +# exit "$code" +# } -on_exit() { - _stop_spinner_on_error - [[ "${VERBOSE:-no}" == "yes" ]] && msg_info "Script exited cleanly" -} +# on_exit() { +# _stop_spinner_on_error +# [[ "${VERBOSE:-no}" == "yes" ]] && msg_info "Script exited cleanly" +# } -on_interrupt() { - _stop_spinner_on_error - msg_error "Interrupted by user (CTRL+C)" - exit 130 -} +# on_interrupt() { +# _stop_spinner_on_error +# msg_error "Interrupted by user (CTRL+C)" +# exit 130 +# } -on_terminate() { - _stop_spinner_on_error - msg_error "Terminated by signal (SIGTERM)" - exit 143 -} +# on_terminate() { +# _stop_spinner_on_error +# msg_error "Terminated by signal (SIGTERM)" +# exit 143 +# } catch_errors() { trap 'on_error' ERR @@ -428,19 +428,19 @@ fatal() { # stop_spinner # } -msg_info() { - local msg="$1" - [[ -z "$msg" || -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return - MSG_INFO_SHOWN["$msg"]=1 +# msg_info() { +# local msg="$1" +# [[ -z "$msg" || -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return +# MSG_INFO_SHOWN["$msg"]=1 - stop_spinner - echo -e "OS: ${var_os:-}" - if [[ "${VERBOSE:-no}" != "no" || "${var_os:-}" == "alpine" || ! -t 2 ]]; then - printf "\r\e[2K%s %b\n" "$HOURGLASS" "${YW}${msg}${CL}" >&2 - else - start_spinner "$msg" - fi -} +# stop_spinner +# echo -e "OS: ${var_os:-}" +# if [[ "${VERBOSE:-no}" != "no" || "${var_os:-}" == "alpine" || ! -t 2 ]]; then +# printf "\r\e[2K%s %b\n" "$HOURGLASS" "${YW}${msg}${CL}" >&2 +# else +# start_spinner "$msg" +# fi +# } spinner() { local chars="/-\|" i=0 From 46fd83db86fa8b493c0b6303e651dbb0e4497eac Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 08:55:19 +0200 Subject: [PATCH 029/463] Update core.func --- misc/core.func | 4 ---- 1 file changed, 4 deletions(-) diff --git a/misc/core.func b/misc/core.func index 8ff46c38..9a02a0aa 100644 --- a/misc/core.func +++ b/misc/core.func @@ -453,8 +453,6 @@ spinner() { msg_info() { local msg="$1" - [[ -z "$msg" || -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return - MSG_INFO_SHOWN["$msg"]=1 echo -ne " ${HOLD:-} ${YW}${msg} " spinner & SPINNER_PID=$! @@ -465,7 +463,6 @@ msg_ok() { printf "\e[?25h" # Show cursor again local msg="$1" echo -e "${BFR:-} ${CM:-✔️} ${GN}${msg}${CL}" - unset MSG_INFO_SHOWN["$msg"] } msg_error() { @@ -480,7 +477,6 @@ msg_warn() { printf "\e[?25h" local msg="$1" echo -e "${BFR:-} ${INFO:-ℹ️} ${YWB}${msg}${CL}" - unset MSG_INFO_SHOWN["$msg"] } msg_custom() { From b8e59597bf96229ede82b274ff6174bd61138695 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 08:57:07 +0200 Subject: [PATCH 030/463] Update core.func --- misc/core.func | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/misc/core.func b/misc/core.func index 9a02a0aa..6ac773b3 100644 --- a/misc/core.func +++ b/misc/core.func @@ -444,13 +444,19 @@ fatal() { spinner() { local chars="/-\|" i=0 - printf "\e[?25l" # Hide cursor + printf "\e[?25l" while true; do printf "\r \e[36m%s\e[0m" "${chars:i++%${#chars}:1}" sleep 0.1 done } +stop_spinner() { + [[ -n "$SPINNER_PID" ]] && kill "$SPINNER_PID" 2>/dev/null && wait "$SPINNER_PID" 2>/dev/null || true + printf "\e[?25h" + SPINNER_PID="" +} + msg_info() { local msg="$1" echo -ne " ${HOLD:-} ${YW}${msg} " @@ -459,22 +465,19 @@ msg_info() { } msg_ok() { - [[ -n "$SPINNER_PID" ]] && kill "$SPINNER_PID" 2>/dev/null - printf "\e[?25h" # Show cursor again + stop_spinner local msg="$1" echo -e "${BFR:-} ${CM:-✔️} ${GN}${msg}${CL}" } msg_error() { - [[ -n "$SPINNER_PID" ]] && kill "$SPINNER_PID" 2>/dev/null - printf "\e[?25h" + stop_spinner local msg="$1" echo -e "${BFR:-} ${CROSS:-✖️} ${RD}${msg}${CL}" } msg_warn() { - [[ -n "$SPINNER_PID" ]] && kill "$SPINNER_PID" 2>/dev/null - printf "\e[?25h" + stop_spinner local msg="$1" echo -e "${BFR:-} ${INFO:-ℹ️} ${YWB}${msg}${CL}" } @@ -484,7 +487,7 @@ msg_custom() { local color="${2:-"\e[36m"}" local msg="${3:-}" [[ -z "$msg" ]] && return - [[ -n "$SPINNER_PID" ]] && kill "$SPINNER_PID" 2>/dev/null + stop_spinner printf "\e[?25h" echo -e "${BFR:-} ${symbol} ${color}${msg}${CL:-\e[0m}" } From 6efcfd1919c25ffe79a8c87b690063874c262db7 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 09:01:50 +0200 Subject: [PATCH 031/463] Update core.func --- misc/core.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/core.func b/misc/core.func index 6ac773b3..9eb41c1e 100644 --- a/misc/core.func +++ b/misc/core.func @@ -443,7 +443,7 @@ fatal() { # } spinner() { - local chars="/-\|" i=0 + local chars="|/-\\·∙•°•∙·" i=0 printf "\e[?25l" while true; do printf "\r \e[36m%s\e[0m" "${chars:i++%${#chars}:1}" From f925b7e89497bd6c465e69087e86bcaae7116e64 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 09:06:31 +0200 Subject: [PATCH 032/463] Update core.func --- misc/core.func | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/misc/core.func b/misc/core.func index 9eb41c1e..dedc2636 100644 --- a/misc/core.func +++ b/misc/core.func @@ -9,16 +9,16 @@ # } # fi -trap 'on_error $? $LINENO' ERR -trap 'on_exit' EXIT -trap 'on_interrupt' INT -trap 'on_terminate' TERM +# trap 'on_error $? $LINENO' ERR +# trap 'on_exit' EXIT +# trap 'on_interrupt' INT +# trap 'on_terminate' TERM -if ! declare -f wait_for >/dev/null; then - wait_for() { - true - } -fi +# if ! declare -f wait_for >/dev/null; then +# wait_for() { +# true +# } +# fi # declare -A MSG_INFO_SHOWN=() # SPINNER_PID="" @@ -120,13 +120,8 @@ _tool_error_hint() { # } catch_errors() { - trap 'on_error' ERR - trap 'on_exit' EXIT - trap 'on_interrupt' INT - trap 'on_terminate' TERM - set -Eeuo pipefail - shopt -s inherit_errexit + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } # ------------------------------------------------------------------------------ From bd08ef9837dc947eb9b2f635b6fed57bd5d36a2b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 09:10:15 +0200 Subject: [PATCH 033/463] Update core.func --- misc/core.func | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/misc/core.func b/misc/core.func index dedc2636..fbd52dcd 100644 --- a/misc/core.func +++ b/misc/core.func @@ -447,9 +447,12 @@ spinner() { } stop_spinner() { - [[ -n "$SPINNER_PID" ]] && kill "$SPINNER_PID" 2>/dev/null && wait "$SPINNER_PID" 2>/dev/null || true - printf "\e[?25h" - SPINNER_PID="" + if [[ -n "$SPINNER_PID" ]]; then + kill "$SPINNER_PID" 2>/dev/null + wait "$SPINNER_PID" 2>/dev/null || true + SPINNER_PID="" + fi + printf "\r\033[K\e[?25h" # clear line + show cursor } msg_info() { From 689e7ae93252cc62dd27c4da260044e4e938095f Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 09:13:00 +0200 Subject: [PATCH 034/463] Update core.func --- misc/core.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/core.func b/misc/core.func index fbd52dcd..e70db260 100644 --- a/misc/core.func +++ b/misc/core.func @@ -438,7 +438,7 @@ fatal() { # } spinner() { - local chars="|/-\\·∙•°•∙·" i=0 + local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏" i=0 printf "\e[?25l" while true; do printf "\r \e[36m%s\e[0m" "${chars:i++%${#chars}:1}" From 6eb096f8af53fe7957ea44e0078f8b31ac0ba315 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 09:15:06 +0200 Subject: [PATCH 035/463] Update core.func --- misc/core.func | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/misc/core.func b/misc/core.func index e70db260..ae03ff74 100644 --- a/misc/core.func +++ b/misc/core.func @@ -447,9 +447,13 @@ spinner() { } stop_spinner() { - if [[ -n "$SPINNER_PID" ]]; then - kill "$SPINNER_PID" 2>/dev/null - wait "$SPINNER_PID" 2>/dev/null || true + local pid="${SPINNER_PID:-}" + [[ -z "$pid" && -f /tmp/spinner.pid ]] && pid=$(/dev/null + wait "$pid" 2>/dev/null || true + rm -f /tmp/spinner.pid SPINNER_PID="" fi printf "\r\033[K\e[?25h" # clear line + show cursor @@ -460,6 +464,7 @@ msg_info() { echo -ne " ${HOLD:-} ${YW}${msg} " spinner & SPINNER_PID=$! + echo "$SPINNER_PID" >/tmp/spinner.pid } msg_ok() { @@ -603,3 +608,5 @@ check_or_create_swap() { return 1 fi } + +trap 'stop_spinner' EXIT INT TERM From b15861d84f9e39e24d32629bac9717cb296f98f0 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 09:26:07 +0200 Subject: [PATCH 036/463] Update core.func --- misc/core.func | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/misc/core.func b/misc/core.func index ae03ff74..ceb1e2f7 100644 --- a/misc/core.func +++ b/misc/core.func @@ -439,23 +439,28 @@ fatal() { spinner() { local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏" i=0 - printf "\e[?25l" - while true; do + printf "\e[?25l" # hide cursor + while :; do printf "\r \e[36m%s\e[0m" "${chars:i++%${#chars}:1}" sleep 0.1 done } stop_spinner() { - local pid="${SPINNER_PID:-}" + local pid + + # Get PID from variable or temp file + pid="${SPINNER_PID:-}" [[ -z "$pid" && -f /tmp/spinner.pid ]] && pid=$(/dev/null - wait "$pid" 2>/dev/null || true + if kill "$pid" 2>/dev/null; then + wait "$pid" 2>/dev/null || true + fi rm -f /tmp/spinner.pid - SPINNER_PID="" + unset SPINNER_PID fi + printf "\r\033[K\e[?25h" # clear line + show cursor } From 0083331c6571944007c2096e37084d04f3cb306e Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 09:34:25 +0200 Subject: [PATCH 037/463] Update core.func --- misc/core.func | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/misc/core.func b/misc/core.func index ceb1e2f7..2e2412fa 100644 --- a/misc/core.func +++ b/misc/core.func @@ -438,38 +438,37 @@ fatal() { # } spinner() { - local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏" i=0 + local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏" + local i=0 printf "\e[?25l" # hide cursor - while :; do + while true; do printf "\r \e[36m%s\e[0m" "${chars:i++%${#chars}:1}" sleep 0.1 done } -stop_spinner() { - local pid - - # Get PID from variable or temp file - pid="${SPINNER_PID:-}" - [[ -z "$pid" && -f /tmp/spinner.pid ]] && pid=$(/dev/null; then - wait "$pid" 2>/dev/null || true - fi - rm -f /tmp/spinner.pid - unset SPINNER_PID - fi - - printf "\r\033[K\e[?25h" # clear line + show cursor -} - msg_info() { local msg="$1" echo -ne " ${HOLD:-} ${YW}${msg} " - spinner & + spinner >/dev/null & SPINNER_PID=$! - echo "$SPINNER_PID" >/tmp/spinner.pid + echo "$SPINNER_PID" >/tmp/.spinner.pid +} + +stop_spinner() { + local pid="${SPINNER_PID:-}" + [[ -z "$pid" && -f /tmp/.spinner.pid ]] && pid=$(/dev/null || true + sleep 0.05 + kill -9 "$pid" 2>/dev/null || true + wait "$pid" 2>/dev/null || true + rm -f /tmp/.spinner.pid + unset SPINNER_PID + fi + + printf "\r\033[K\e[?25h" # clear line + restore cursor } msg_ok() { From a40041f87555ba402459ced67407fe65d3e54239 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 10:29:00 +0200 Subject: [PATCH 038/463] Update core.func --- misc/core.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/core.func b/misc/core.func index 2e2412fa..63395c76 100644 --- a/misc/core.func +++ b/misc/core.func @@ -450,7 +450,7 @@ spinner() { msg_info() { local msg="$1" echo -ne " ${HOLD:-} ${YW}${msg} " - spinner >/dev/null & + spinner SPINNER_PID=$! echo "$SPINNER_PID" >/tmp/.spinner.pid } From e2de55ac7a1ba284b4feef0c31c03eab20f93728 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 10:38:29 +0200 Subject: [PATCH 039/463] test --- misc/build.func | 154 ++++++++++++++++++++++++------------------------ misc/core.func | 2 +- 2 files changed, 78 insertions(+), 78 deletions(-) diff --git a/misc/build.func b/misc/build.func index f6f8e582..7013e073 100644 --- a/misc/build.func +++ b/misc/build.func @@ -186,92 +186,92 @@ ssh_check() { fi } -select_storage() { - local CLASS=$1 CONTENT CONTENT_LABEL - case $CLASS in - container) - CONTENT='rootdir' - CONTENT_LABEL='Container' - ;; - template) - CONTENT='vztmpl' - CONTENT_LABEL='Template' - ;; - iso) - CONTENT='iso' - CONTENT_LABEL='ISO image' - ;; - images) - CONTENT='images' - CONTENT_LABEL='VM Disk image' - ;; - backup) - CONTENT='backup' - CONTENT_LABEL='Backup' - ;; - snippets) - CONTENT='snippets' - CONTENT_LABEL='Snippets' - ;; - *) - msg_error "Invalid storage class '$CLASS'." - exit 201 - ;; - esac +# select_storage() { +# local CLASS=$1 CONTENT CONTENT_LABEL +# case $CLASS in +# container) +# CONTENT='rootdir' +# CONTENT_LABEL='Container' +# ;; +# template) +# CONTENT='vztmpl' +# CONTENT_LABEL='Template' +# ;; +# iso) +# CONTENT='iso' +# CONTENT_LABEL='ISO image' +# ;; +# images) +# CONTENT='images' +# CONTENT_LABEL='VM Disk image' +# ;; +# backup) +# CONTENT='backup' +# CONTENT_LABEL='Backup' +# ;; +# snippets) +# CONTENT='snippets' +# CONTENT_LABEL='Snippets' +# ;; +# *) +# msg_error "Invalid storage class '$CLASS'." +# exit 201 +# ;; +# esac - command -v whiptail >/dev/null || { - msg_error "whiptail missing." - exit 220 - } - command -v numfmt >/dev/null || { - msg_error "numfmt missing." - exit 221 - } +# command -v whiptail >/dev/null || { +# msg_error "whiptail missing." +# exit 220 +# } +# command -v numfmt >/dev/null || { +# msg_error "numfmt missing." +# exit 221 +# } - local -a MENU - while read -r line; do - local TAG=$(echo "$line" | awk '{print $1}') - local TYPE=$(echo "$line" | awk '{printf "%-10s", $2}') - local FREE=$(echo "$line" | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf "%9sB", $6}') - MENU+=("$TAG" "Type: $TYPE Free: $FREE" "OFF") - done < <(pvesm status -content "$CONTENT" | awk 'NR>1') +# local -a MENU +# while read -r line; do +# local TAG=$(echo "$line" | awk '{print $1}') +# local TYPE=$(echo "$line" | awk '{printf "%-10s", $2}') +# local FREE=$(echo "$line" | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf "%9sB", $6}') +# MENU+=("$TAG" "Type: $TYPE Free: $FREE" "OFF") +# done < <(pvesm status -content "$CONTENT" | awk 'NR>1') - if [ ${#MENU[@]} -eq 0 ]; then - msg_error "No storage found for content type '$CONTENT'." - exit 203 - fi +# if [ ${#MENU[@]} -eq 0 ]; then +# msg_error "No storage found for content type '$CONTENT'." +# exit 203 +# fi - if [ $((${#MENU[@]} / 3)) -eq 1 ]; then - echo "${MENU[0]}" - return - fi +# if [ $((${#MENU[@]} / 3)) -eq 1 ]; then +# echo "${MENU[0]}" +# return +# fi - local STORAGE - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ - 16 70 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { - msg_error "Storage selection cancelled by user." - exit 202 - } - echo "$STORAGE" -} +# local STORAGE +# STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ +# "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ +# 16 70 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { +# msg_error "Storage selection cancelled by user." +# exit 202 +# } +# echo "$STORAGE" +# } -manage_default_storage() { - local file="/usr/local/community-scripts/default_storage" - mkdir -p /usr/local/community-scripts +# manage_default_storage() { +# local file="/usr/local/community-scripts/default_storage" +# mkdir -p /usr/local/community-scripts - local tmpl=$(select_storage template) - local cont=$(select_storage container) +# local tmpl=$(select_storage template) +# local cont=$(select_storage container) - cat <"$file" -TEMPLATE_STORAGE=$tmpl -CONTAINER_STORAGE=$cont -EOF +# cat <"$file" +# TEMPLATE_STORAGE=$tmpl +# CONTAINER_STORAGE=$cont +# EOF - msg_ok "Default Storage set: Template=${BL}$tmpl${CL} ${GN}|${CL} Container=${BL}$cont${CL}" - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --msgbox "Default Storage set:\n\nTemplate: $tmpl\nContainer: $cont" 10 58 -} +# msg_ok "Default Storage set: Template=${BL}$tmpl${CL} ${GN}|${CL} Container=${BL}$cont${CL}" +# whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ +# --msgbox "Default Storage set:\n\nTemplate: $tmpl\nContainer: $cont" 10 58 +# } base_settings() { # Default Settings diff --git a/misc/core.func b/misc/core.func index 63395c76..01101ae3 100644 --- a/misc/core.func +++ b/misc/core.func @@ -450,7 +450,7 @@ spinner() { msg_info() { local msg="$1" echo -ne " ${HOLD:-} ${YW}${msg} " - spinner + spinner & SPINNER_PID=$! echo "$SPINNER_PID" >/tmp/.spinner.pid } From bdcdc8b794d67b6539fca442ff298f4aefcd0cd9 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:01:44 +0200 Subject: [PATCH 040/463] Update core.func --- misc/core.func | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/core.func b/misc/core.func index 01101ae3..87284fca 100644 --- a/misc/core.func +++ b/misc/core.func @@ -467,14 +467,14 @@ stop_spinner() { rm -f /tmp/.spinner.pid unset SPINNER_PID fi - - printf "\r\033[K\e[?25h" # clear line + restore cursor + printf "\r\033[K" } msg_ok() { stop_spinner local msg="$1" echo -e "${BFR:-} ${CM:-✔️} ${GN}${msg}${CL}" + printf "\e[?25h" } msg_error() { From 414d82733ef284f132e256bf14b163809bbc59cc Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:18:18 +0200 Subject: [PATCH 041/463] test --- ct/debian.sh | 4 ++-- misc/core.func | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/debian.sh b/ct/debian.sh index c3816577..c525e5e2 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -40,5 +40,5 @@ start build_container description -msg_ok "Completed Successfully!\n" -echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +msg_ok "Completed Successfully!" +msg_custom "🚀" "${GN}" "${APP} setup has been successfully initialized!" diff --git a/misc/core.func b/misc/core.func index 87284fca..ed2fe2aa 100644 --- a/misc/core.func +++ b/misc/core.func @@ -495,8 +495,8 @@ msg_custom() { local msg="${3:-}" [[ -z "$msg" ]] && return stop_spinner - printf "\e[?25h" echo -e "${BFR:-} ${symbol} ${color}${msg}${CL:-\e[0m}" + printf "\r\033[K\e[?25h\n" # Zeile räumen, Cursor wiederherstellen und Zeilenumbruch! } # msg_ok() { From 49281943c36401d947029f072c30beb743303b1e Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:22:08 +0200 Subject: [PATCH 042/463] Update core.func --- misc/core.func | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/misc/core.func b/misc/core.func index ed2fe2aa..ea5c3f88 100644 --- a/misc/core.func +++ b/misc/core.func @@ -453,6 +453,7 @@ msg_info() { spinner & SPINNER_PID=$! echo "$SPINNER_PID" >/tmp/.spinner.pid + disown "$SPINNER_PID" 2>/dev/null || true } stop_spinner() { @@ -460,14 +461,18 @@ stop_spinner() { [[ -z "$pid" && -f /tmp/.spinner.pid ]] && pid=$(/dev/null || true - sleep 0.05 - kill -9 "$pid" 2>/dev/null || true - wait "$pid" 2>/dev/null || true + if kill "$pid" 2>/dev/null; then + sleep 0.05 + kill -9 "$pid" 2>/dev/null || true + wait "$pid" 2>/dev/null || true + fi rm -f /tmp/.spinner.pid unset SPINNER_PID fi - printf "\r\033[K" + + # Aufräumen, egal was oben passiert ist + stty sane 2>/dev/null + printf "\r\033[K\e[?25h\n" } msg_ok() { From e7a00d483c3f415615763487eea827afdd4851af Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:24:43 +0200 Subject: [PATCH 043/463] Update core.func --- misc/core.func | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/core.func b/misc/core.func index ea5c3f88..67537c4b 100644 --- a/misc/core.func +++ b/misc/core.func @@ -479,7 +479,6 @@ msg_ok() { stop_spinner local msg="$1" echo -e "${BFR:-} ${CM:-✔️} ${GN}${msg}${CL}" - printf "\e[?25h" } msg_error() { From 86a4851c7c082cc6efc1b4872dc077fe40bbb235 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:28:25 +0200 Subject: [PATCH 044/463] Update create_lxc.sh --- misc/create_lxc.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 9bf6dd6c..4fdddf7f 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -107,14 +107,16 @@ function select_storage() { } local -a MENU - local -A SEEN=() + local KEYS_SEEN="" local MSG_MAX_LENGTH=0 while read -r TAG TYPE _ _ _ FREE _; do [[ -n "$TAG" && -n "$TYPE" ]] || continue local KEY="${TAG}:${TYPE}" - [[ -z "${SEEN[$KEY]}" ]] || continue - SEEN["$KEY"]=1 + if echo "$KEYS_SEEN" | grep -qx "$KEY"; then + continue + fi + KEYS_SEEN="${KEYS_SEEN}"$'\n'"$KEY" local TYPE_PADDED=$(printf "%-10s" "$TYPE") local FREE_FMT=$(numfmt --to=iec --from-unit=K --format %.2f <<<"$FREE")B From 57171c0ae8344be596e429d6812cee9735e2d3d2 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:36:02 +0200 Subject: [PATCH 045/463] Update core.func --- misc/core.func | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/core.func b/misc/core.func index 67537c4b..029411b4 100644 --- a/misc/core.func +++ b/misc/core.func @@ -438,19 +438,19 @@ fatal() { # } spinner() { + local msg="$1" local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏" local i=0 - printf "\e[?25l" # hide cursor while true; do - printf "\r \e[36m%s\e[0m" "${chars:i++%${#chars}:1}" + printf "\r\e[2K\e[36m%s\e[0m ${YW}%s${CL}" "${chars:i++%${#chars}:1}" "$msg" sleep 0.1 done } msg_info() { local msg="$1" - echo -ne " ${HOLD:-} ${YW}${msg} " - spinner & + printf "\e[?25l" # hide cursor + spinner "$msg" & SPINNER_PID=$! echo "$SPINNER_PID" >/tmp/.spinner.pid disown "$SPINNER_PID" 2>/dev/null || true From 7b1b1c2263f6555b832aa8afe688a698d8ae8632 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:39:14 +0200 Subject: [PATCH 046/463] Update create_lxc.sh --- misc/create_lxc.sh | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 4fdddf7f..f7879ee5 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -108,9 +108,9 @@ function select_storage() { local -a MENU local KEYS_SEEN="" - local MSG_MAX_LENGTH=0 + local COL_WIDTH=0 - while read -r TAG TYPE _ _ _ FREE _; do + while read -r TAG TYPE _ USED FREE _; do [[ -n "$TAG" && -n "$TYPE" ]] || continue local KEY="${TAG}:${TYPE}" if echo "$KEYS_SEEN" | grep -qx "$KEY"; then @@ -118,12 +118,14 @@ function select_storage() { fi KEYS_SEEN="${KEYS_SEEN}"$'\n'"$KEY" - local TYPE_PADDED=$(printf "%-10s" "$TYPE") - local FREE_FMT=$(numfmt --to=iec --from-unit=K --format %.2f <<<"$FREE")B - local ITEM="Type: $TYPE_PADDED Free: $FREE_FMT" - ((${#ITEM} + 2 > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=$((${#ITEM} + 2)) + local NAME_TYPE="${TAG} (${TYPE})" + local USED_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$USED") + local FREE_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$FREE") + local INFO="Used: $USED_FMTB Free: $FREE_FMTB" - MENU+=("$KEY" "$ITEM" "OFF") + ((${#NAME_TYPE} > COL_WIDTH)) && COL_WIDTH=${#NAME_TYPE} + + MENU+=("$KEY" "$NAME_TYPE | $INFO" "OFF") done < <(pvesm status -content "$CONTENT" | awk 'NR>1') if [ ${#MENU[@]} -eq 0 ]; then @@ -136,10 +138,11 @@ function select_storage() { return fi + local WIDTH=$((COL_WIDTH + 42)) local STORAGE STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ - 16 $((MSG_MAX_LENGTH + 23)) 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { + 16 "$WIDTH" 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { msg_error "Storage selection cancelled by user." exit 202 } From 50bed47912d353451dff0ed36a1bd6c70c9c7b36 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:41:07 +0200 Subject: [PATCH 047/463] Update create_lxc.sh --- misc/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index f7879ee5..266bc7b2 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -121,7 +121,7 @@ function select_storage() { local NAME_TYPE="${TAG} (${TYPE})" local USED_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$USED") local FREE_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$FREE") - local INFO="Used: $USED_FMTB Free: $FREE_FMTB" + local INFO="Used: ${USED_FMT}B Free: ${FREE_FMT}B" ((${#NAME_TYPE} > COL_WIDTH)) && COL_WIDTH=${#NAME_TYPE} From 6bd17445282545abc1b4092e7f0f4d120f5b373d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:42:04 +0200 Subject: [PATCH 048/463] Update create_lxc.sh --- misc/create_lxc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 266bc7b2..122c9b3f 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -98,11 +98,11 @@ function select_storage() { esac command -v whiptail >/dev/null || { - msg_error "whiptail missing." + msg_error "whiptail missing. Please install whiptail." exit 220 } command -v numfmt >/dev/null || { - msg_error "numfmt missing." + msg_error "numfmt missing. Please install numfmt (coreutils package)." exit 221 } From 4e7352b2c5924893e3f17d8b3130564375a2cbde Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:44:24 +0200 Subject: [PATCH 049/463] Update create_lxc.sh --- misc/create_lxc.sh | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 122c9b3f..c4e004e7 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -98,11 +98,11 @@ function select_storage() { esac command -v whiptail >/dev/null || { - msg_error "whiptail missing. Please install whiptail." + msg_error "whiptail missing." exit 220 } command -v numfmt >/dev/null || { - msg_error "numfmt missing. Please install numfmt (coreutils package)." + msg_error "numfmt missing." exit 221 } @@ -113,19 +113,16 @@ function select_storage() { while read -r TAG TYPE _ USED FREE _; do [[ -n "$TAG" && -n "$TYPE" ]] || continue local KEY="${TAG}:${TYPE}" - if echo "$KEYS_SEEN" | grep -qx "$KEY"; then - continue - fi + if echo "$KEYS_SEEN" | grep -qx "$KEY"; then continue; fi KEYS_SEEN="${KEYS_SEEN}"$'\n'"$KEY" - local NAME_TYPE="${TAG} (${TYPE})" local USED_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$USED") local FREE_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$FREE") - local INFO="Used: ${USED_FMT}B Free: ${FREE_FMT}B" + local DISPLAY_NAME="${TAG} (${TYPE})" + local INFO="Free: ${FREE_FMT}B Used: ${USED_FMT}B" - ((${#NAME_TYPE} > COL_WIDTH)) && COL_WIDTH=${#NAME_TYPE} - - MENU+=("$KEY" "$NAME_TYPE | $INFO" "OFF") + ((${#DISPLAY_NAME} > COL_WIDTH)) && COL_WIDTH=${#DISPLAY_NAME} + MENU+=("$KEY" "${DISPLAY_NAME} | ${INFO}" "OFF") done < <(pvesm status -content "$CONTENT" | awk 'NR>1') if [ ${#MENU[@]} -eq 0 ]; then From 555d83b51177089eb7dbd9779961f7bc3bc6cac9 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:48:14 +0200 Subject: [PATCH 050/463] Update create_lxc.sh --- misc/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index c4e004e7..8f2c5751 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -110,7 +110,7 @@ function select_storage() { local KEYS_SEEN="" local COL_WIDTH=0 - while read -r TAG TYPE _ USED FREE _; do + while read -r TAG TYPE _ TOTAL USED FREE _; do [[ -n "$TAG" && -n "$TYPE" ]] || continue local KEY="${TAG}:${TYPE}" if echo "$KEYS_SEEN" | grep -qx "$KEY"; then continue; fi From fb849cf02d65d77531da48187d884eac8da064e3 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:51:21 +0200 Subject: [PATCH 051/463] Update create_lxc.sh --- misc/create_lxc.sh | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 8f2c5751..5874ac69 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -107,22 +107,18 @@ function select_storage() { } local -a MENU - local KEYS_SEEN="" + local -A STORAGE_MAP=() local COL_WIDTH=0 while read -r TAG TYPE _ TOTAL USED FREE _; do [[ -n "$TAG" && -n "$TYPE" ]] || continue - local KEY="${TAG}:${TYPE}" - if echo "$KEYS_SEEN" | grep -qx "$KEY"; then continue; fi - KEYS_SEEN="${KEYS_SEEN}"$'\n'"$KEY" - + local DISPLAY="${TAG} (${TYPE})" local USED_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$USED") local FREE_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$FREE") - local DISPLAY_NAME="${TAG} (${TYPE})" local INFO="Free: ${FREE_FMT}B Used: ${USED_FMT}B" - - ((${#DISPLAY_NAME} > COL_WIDTH)) && COL_WIDTH=${#DISPLAY_NAME} - MENU+=("$KEY" "${DISPLAY_NAME} | ${INFO}" "OFF") + STORAGE_MAP["$DISPLAY"]="$TAG" # Map DISPLAY to actual TAG + MENU+=("$DISPLAY" "$INFO" "OFF") + ((${#DISPLAY} > COL_WIDTH)) && COL_WIDTH=${#DISPLAY} done < <(pvesm status -content "$CONTENT" | awk 'NR>1') if [ ${#MENU[@]} -eq 0 ]; then @@ -131,20 +127,20 @@ function select_storage() { fi if [ $((${#MENU[@]} / 3)) -eq 1 ]; then - echo "${MENU[0]%%:*}" + echo "${STORAGE_MAP[${MENU[0]}]}" return fi local WIDTH=$((COL_WIDTH + 42)) - local STORAGE - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ + local DISPLAY_SELECTED + DISPLAY_SELECTED=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ 16 "$WIDTH" 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { msg_error "Storage selection cancelled by user." exit 202 } - echo "${STORAGE%%:*}" + echo "${STORAGE_MAP["$DISPLAY_SELECTED"]}" } # Test if required variables are set From a9efa6d61538f12ae50da087fb755b0f826f50e6 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 12:36:15 +0200 Subject: [PATCH 052/463] Update core.func --- misc/core.func | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/misc/core.func b/misc/core.func index 029411b4..521d3679 100644 --- a/misc/core.func +++ b/misc/core.func @@ -442,7 +442,7 @@ spinner() { local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏" local i=0 while true; do - printf "\r\e[2K\e[36m%s\e[0m ${YW}%s${CL}" "${chars:i++%${#chars}:1}" "$msg" + printf "\r\e[2K\e[36m%s\e[0m ${YW}%s${CL}" "${YW}${chars:i++%${#chars}:1}" "$msg" sleep 0.1 done } @@ -470,9 +470,8 @@ stop_spinner() { unset SPINNER_PID fi - # Aufräumen, egal was oben passiert ist stty sane 2>/dev/null - printf "\r\033[K\e[?25h\n" + #printf "\r\033[K\e[?25h\n" } msg_ok() { From e2b33beea7cc461e1b85c59ab98c87bb21c8bfd3 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 12:40:49 +0200 Subject: [PATCH 053/463] Update core.func --- misc/core.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/core.func b/misc/core.func index 521d3679..310dee42 100644 --- a/misc/core.func +++ b/misc/core.func @@ -442,7 +442,7 @@ spinner() { local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏" local i=0 while true; do - printf "\r\e[2K\e[36m%s\e[0m ${YW}%s${CL}" "${YW}${chars:i++%${#chars}:1}" "$msg" + printf "\r\e[2K\e[36m%s\e[0m ${YW}%s${CL}" "${chars:i++%${#chars}:1}" "$msg" sleep 0.1 done } From 14c99239cb9f97683f1fcf16d6f5595bb507e179 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 12:44:51 +0200 Subject: [PATCH 054/463] Update core.func --- misc/core.func | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/misc/core.func b/misc/core.func index 310dee42..e6bb2d22 100644 --- a/misc/core.func +++ b/misc/core.func @@ -438,24 +438,14 @@ fatal() { # } spinner() { - local msg="$1" local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏" local i=0 while true; do - printf "\r\e[2K\e[36m%s\e[0m ${YW}%s${CL}" "${chars:i++%${#chars}:1}" "$msg" + printf "\r\e[2K%s %b" "${YWB}${chars:i++%${#chars}:1}${CL}" "${YWB}${SPINNER_MSG:-}${CL}" sleep 0.1 done } -msg_info() { - local msg="$1" - printf "\e[?25l" # hide cursor - spinner "$msg" & - SPINNER_PID=$! - echo "$SPINNER_PID" >/tmp/.spinner.pid - disown "$SPINNER_PID" 2>/dev/null || true -} - stop_spinner() { local pid="${SPINNER_PID:-}" [[ -z "$pid" && -f /tmp/.spinner.pid ]] && pid=$(/tmp/.spinner.pid + disown "$SPINNER_PID" 2>/dev/null || true +} + msg_ok() { stop_spinner local msg="$1" From d60f0ebd72f7e876572c41db627846fea17b148b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 12:49:27 +0200 Subject: [PATCH 055/463] Update core.func --- misc/core.func | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/misc/core.func b/misc/core.func index e6bb2d22..6a14a886 100644 --- a/misc/core.func +++ b/misc/core.func @@ -138,6 +138,13 @@ color() { CL=$(echo "\033[m") } +# Special for spinner and colorized output via printf +color_spinner() { + CS_YW=$'\033[33m' + CS_YWB=$'\033[93m' + CS_CL=$'\033[m' +} + # ------------------------------------------------------------------------------ # Defines formatting helpers like tab, bold, and line reset sequences. # ------------------------------------------------------------------------------ @@ -438,10 +445,11 @@ fatal() { # } spinner() { - local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏" + local chars=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏) local i=0 while true; do - printf "\r\e[2K%s %b" "${YWB}${chars:i++%${#chars}:1}${CL}" "${YWB}${SPINNER_MSG:-}${CL}" + local index=$((i++ % ${#chars[@]})) + printf "\r\033[2K%s %b" "${CS_YWB}${chars[$index]}${CS_CL}" "${CS_YWB}${SPINNER_MSG:-}${CS_CL}" sleep 0.1 done } @@ -467,6 +475,7 @@ stop_spinner() { msg_info() { local msg="$1" SPINNER_MSG="$msg" + color_spinner spinner & SPINNER_PID=$! echo "$SPINNER_PID" >/tmp/.spinner.pid @@ -498,7 +507,7 @@ msg_custom() { [[ -z "$msg" ]] && return stop_spinner echo -e "${BFR:-} ${symbol} ${color}${msg}${CL:-\e[0m}" - printf "\r\033[K\e[?25h\n" # Zeile räumen, Cursor wiederherstellen und Zeilenumbruch! + printf "\r\033[K\e[?25h\n" } # msg_ok() { From 2637a700574dc449c2eaf11145e6f0e0ac0c45dc Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:12:35 +0200 Subject: [PATCH 056/463] Update install.func --- misc/install.func | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/misc/install.func b/misc/install.func index efc77be5..acecf3f3 100644 --- a/misc/install.func +++ b/misc/install.func @@ -65,7 +65,8 @@ setting_up_container() { rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED systemctl disable -q --now systemd-networkd-wait-online.service msg_ok "Set up Container OS" - msg_custom "${CM}" "${GN}" "Network Connected: ${BL}$(hostname -I)" + #msg_custom "${CM}" "${GN}" "Network Connected: ${BL}$(hostname -I)" + msg_ok "Network Connected: ${BL}$(hostname -I)" } # This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected @@ -104,24 +105,24 @@ network_check() { fi # DNS resolution checks for GitHub-related domains (IPv4 and/or IPv6) - GITHUB_HOSTS=("github.com" "raw.githubusercontent.com" "api.github.com" "git.community-scripts.org") - GITHUB_STATUS="GitHub DNS:" + GIT_HOSTS=("github.com" "raw.githubusercontent.com" "api.github.com" "git.community-scripts.org") + GIT_STATUS="Git DNS:" DNS_FAILED=false - for HOST in "${GITHUB_HOSTS[@]}"; do + for HOST in "${GIT_HOSTS[@]}"; do RESOLVEDIP=$(getent hosts "$HOST" | awk '{ print $1 }' | grep -E '(^([0-9]{1,3}\.){3}[0-9]{1,3}$)|(^[a-fA-F0-9:]+$)' | head -n1) if [[ -z "$RESOLVEDIP" ]]; then - GITHUB_STATUS+="$HOST:($DNSFAIL)" + GIT_STATUS+="$HOST:($DNSFAIL)" DNS_FAILED=true else - GITHUB_STATUS+=" $HOST:($DNSOK)" + GIT_STATUS+=" $HOST:($DNSOK)" fi done if [[ "$DNS_FAILED" == true ]]; then - fatal "$GITHUB_STATUS" + fatal "$GIT_STATUS" else - msg_ok "$GITHUB_STATUS" + msg_ok "$GIT_STATUS" fi set -e From e33505fcce0c0b8d478df444cd256a465f01a560 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:13:48 +0200 Subject: [PATCH 057/463] Update build.func --- misc/build.func | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/misc/build.func b/misc/build.func index 7013e073..f9724d4b 100644 --- a/misc/build.func +++ b/misc/build.func @@ -403,13 +403,12 @@ echo_default() { fi # Output the selected values with icons - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os$ ($var_version$){CL}" echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" if [ "$VERB" == "yes" ]; then echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}" fi From 8d63c9d23b4cb466d7434969b075ed18e9eb2938 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:15:02 +0200 Subject: [PATCH 058/463] Update build.func --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index f9724d4b..957c931a 100644 --- a/misc/build.func +++ b/misc/build.func @@ -404,7 +404,7 @@ echo_default() { # Output the selected values with icons echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os$ ($var_version$){CL}" + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os$ ($var_version)${CL}" echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" From 0e1f7eb7f598d071d7656814c8d3dded9ccc0b43 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:22:43 +0200 Subject: [PATCH 059/463] Update build.func --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 957c931a..96eb87a3 100644 --- a/misc/build.func +++ b/misc/build.func @@ -404,7 +404,7 @@ echo_default() { # Output the selected values with icons echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os$ ($var_version)${CL}" + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os ($var_version)${CL}" echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" From 9f7512ec93be8f4888f70359e4b7d27ddbe7f97f Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:25:03 +0000 Subject: [PATCH 060/463] Update .app files (#651) Co-authored-by: GitHub Actions --- ct/headers/scraparr | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ct/headers/scraparr diff --git a/ct/headers/scraparr b/ct/headers/scraparr new file mode 100644 index 00000000..5e5b3f94 --- /dev/null +++ b/ct/headers/scraparr @@ -0,0 +1,6 @@ + _____ + / ___/______________ _____ ____ ___________ + \__ \/ ___/ ___/ __ `/ __ \/ __ `/ ___/ ___/ + ___/ / /__/ / / /_/ / /_/ / /_/ / / / / +/____/\___/_/ \__,_/ .___/\__,_/_/ /_/ + /_/ From f8ec627fa05ff9bc89a048b950deab02eb90f870 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:25:41 +0000 Subject: [PATCH 061/463] Update .app files (#652) Co-authored-by: GitHub Actions --- ct/headers/librespeed-rust | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ct/headers/librespeed-rust diff --git a/ct/headers/librespeed-rust b/ct/headers/librespeed-rust new file mode 100644 index 00000000..0300b747 --- /dev/null +++ b/ct/headers/librespeed-rust @@ -0,0 +1,6 @@ + __ _ __ __ ____ __ + / / (_) /_ ________ _________ ___ ___ ____/ / / __ \__ _______/ /_ + / / / / __ \/ ___/ _ \/ ___/ __ \/ _ \/ _ \/ __ / / /_/ / / / / ___/ __/ + / /___/ / /_/ / / / __(__ ) /_/ / __/ __/ /_/ / / _, _/ /_/ (__ ) /_ +/_____/_/_.___/_/ \___/____/ .___/\___/\___/\__,_/ /_/ |_|\__,_/____/\__/ + /_/ From 7ca204b827d37f2bb8c1ac4c2bada91062f8b54f Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:39:39 +0200 Subject: [PATCH 062/463] fix path --- misc/{ => backup_07052025}/api.func.bak | 0 misc/{ => backup_07052025}/backup.func | 0 misc/build.func | 2 +- misc/install.func | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) rename misc/{ => backup_07052025}/api.func.bak (100%) rename misc/{ => backup_07052025}/backup.func (100%) diff --git a/misc/api.func.bak b/misc/backup_07052025/api.func.bak similarity index 100% rename from misc/api.func.bak rename to misc/backup_07052025/api.func.bak diff --git a/misc/backup.func b/misc/backup_07052025/backup.func similarity index 100% rename from misc/backup.func rename to misc/backup_07052025/backup.func diff --git a/misc/build.func b/misc/build.func index 96eb87a3..8d03ff53 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1290,7 +1290,7 @@ EOF' fi msg_ok "Customized LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/"$var_install".sh)" $? + lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/"$var_install".sh)" $? } # This function sets the description of the container. diff --git a/misc/install.func b/misc/install.func index acecf3f3..ddb78bc9 100644 --- a/misc/install.func +++ b/misc/install.func @@ -31,7 +31,7 @@ catch_errors() { # This function handles errors error_handler() { - source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) + source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/api.func) printf "\e[?25h" local exit_code="$?" local line_number="$1" From 4f4fd0d125b0f52a44fa0a36297d35a5e457ba0b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:44:27 +0200 Subject: [PATCH 063/463] Update lxc-delete.sh --- tools/pve/lxc-delete.sh | 52 ++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/tools/pve/lxc-delete.sh b/tools/pve/lxc-delete.sh index 8cadfda0..290f97d0 100644 --- a/tools/pve/lxc-delete.sh +++ b/tools/pve/lxc-delete.sh @@ -50,19 +50,23 @@ if [ -z "$containers" ]; then exit 1 fi -menu_items=("ALL" "Delete ALL containers" "OFF") # Add as first option -FORMAT="%-10s %-15s %-10s" +menu_items=("ALL" "Delete ALL containers" "OFF") +FORMAT="%-10s %-10s %-10s %-10s" while read -r container; do container_id=$(echo $container | awk '{print $1}') container_name=$(echo $container | awk '{print $2}') container_status=$(echo $container | awk '{print $3}') - formatted_line=$(printf "$FORMAT" "$container_name" "$container_status") + container_os=$(echo $container | awk '{print $4}') + protected=$(pct config $container_id | grep -i '^protection:' | awk '{print $2}') + is_protected="No" + [[ "$protected" == "1" ]] && is_protected="Yes" + formatted_line=$(printf "$FORMAT" "$container_name" "$container_status" "$container_os" "$is_protected") menu_items+=("$container_id" "$formatted_line" "OFF") done <<<"$containers" CHOICES=$(whiptail --title "LXC Container Delete" \ - --checklist "Select LXC containers to delete:" 25 60 13 \ + --checklist "Select LXC containers to delete:\n\nNAME STATUS OS PROTECTED" 25 70 15 \ "${menu_items[@]}" 3>&2 2>&1 1>&3) if [ -z "$CHOICES" ]; then @@ -76,17 +80,32 @@ DELETE_MODE=${DELETE_MODE:-m} selected_ids=$(echo "$CHOICES" | tr -d '"' | tr -s ' ' '\n') -# If "ALL" is selected, override with all container IDs +# Wenn ALL ausgewählt ist, überschreiben if echo "$selected_ids" | grep -q "^ALL$"; then selected_ids=$(echo "$containers" | awk '{print $1}') fi for container_id in $selected_ids; do - status=$(pct status $container_id) + status=$(pct status "$container_id") + protected=$(pct config "$container_id" | grep -i '^protection:' | awk '{print $2}') + is_protected="No" + [[ "$protected" == "1" ]] && is_protected="Yes" + + if [[ "$is_protected" == "Yes" && "$DELETE_MODE" == "a" ]]; then + echo -e "${BL}[Info]${RD} Skipping protected container $container_id (auto mode).${CL}" + continue + fi if [ "$status" == "status: running" ]; then + if [[ "$is_protected" == "Yes" && "$DELETE_MODE" == "m" ]]; then + read -p "⚠️ Container $container_id is PROTECTED. Delete anyway? (y/N): " CONFIRM_PROTECTED + [[ ! "$CONFIRM_PROTECTED" =~ ^[Yy]$ ]] && { + echo -e "${BL}[Info]${RD} Skipping protected container $container_id...${CL}" + continue + } + fi echo -e "${BL}[Info]${GN} Stopping container $container_id...${CL}" - pct stop $container_id & + pct stop "$container_id" & sleep 5 echo -e "${BL}[Info]${GN} Container $container_id stopped.${CL}" fi @@ -96,15 +115,30 @@ for container_id in $selected_ids; do pct destroy "$container_id" -f & pid=$! spinner $pid - [ $? -eq 0 ] && echo "Container $container_id deleted." || whiptail --title "Error" --msgbox "Failed to delete container $container_id." 10 60 + if [ $? -eq 0 ]; then + echo "Container $container_id deleted." + else + whiptail --title "Error" --msgbox "Failed to delete container $container_id." 10 60 + fi else read -p "Delete container $container_id? (y/N): " CONFIRM if [[ "$CONFIRM" =~ ^[Yy]$ ]]; then + if [[ "$is_protected" == "Yes" ]]; then + read -p "⚠️ Container $container_id is PROTECTED. Delete anyway? (y/N): " CONFIRM_PROTECTED + [[ ! "$CONFIRM_PROTECTED" =~ ^[Yy]$ ]] && { + echo -e "${BL}[Info]${RD} Skipping protected container $container_id...${CL}" + continue + } + fi echo -e "${BL}[Info]${GN} Deleting container $container_id...${CL}" pct destroy "$container_id" -f & pid=$! spinner $pid - [ $? -eq 0 ] && echo "Container $container_id deleted." || whiptail --title "Error" --msgbox "Failed to delete container $container_id." 10 60 + if [ $? -eq 0 ]; then + echo "Container $container_id deleted." + else + whiptail --title "Error" --msgbox "Failed to delete container $container_id." 10 60 + fi else echo -e "${BL}[Info]${RD} Skipping container $container_id...${CL}" fi From 2ccd4f8318a3557e4851a9186dac912ee6cdc7ad Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:47:14 +0200 Subject: [PATCH 064/463] Update lxc-delete.sh --- tools/pve/lxc-delete.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/pve/lxc-delete.sh b/tools/pve/lxc-delete.sh index 290f97d0..45d1b67b 100644 --- a/tools/pve/lxc-delete.sh +++ b/tools/pve/lxc-delete.sh @@ -40,8 +40,10 @@ CM="${TAB}✔️${TAB}${CL}" header_info echo "Loading..." -whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Deletion" --yesno "This will delete LXC containers. Proceed?" 10 58 - +if ! whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Deletion" --yesno "This will delete LXC containers. Proceed?" 10 58; then + echo -e "${RD}Aborted by user.${CL}" + exit 0 +fi NODE=$(hostname) containers=$(pct list | tail -n +2 | awk '{print $0 " " $4}') From 5e3ccb265f8021813ef70cab990f93b6afa44f6a Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:54:59 +0200 Subject: [PATCH 065/463] Update lxc-delete.sh --- tools/pve/lxc-delete.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pve/lxc-delete.sh b/tools/pve/lxc-delete.sh index 45d1b67b..cb413f33 100644 --- a/tools/pve/lxc-delete.sh +++ b/tools/pve/lxc-delete.sh @@ -65,7 +65,7 @@ while read -r container; do [[ "$protected" == "1" ]] && is_protected="Yes" formatted_line=$(printf "$FORMAT" "$container_name" "$container_status" "$container_os" "$is_protected") menu_items+=("$container_id" "$formatted_line" "OFF") -done <<<"$containers" +done < <(printf '%s\n' "$containers") CHOICES=$(whiptail --title "LXC Container Delete" \ --checklist "Select LXC containers to delete:\n\nNAME STATUS OS PROTECTED" 25 70 15 \ From e5b1668f68407a52be87d56c0bee01c31c22b04e Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:01:17 +0200 Subject: [PATCH 066/463] Update lxc-delete.sh --- tools/pve/lxc-delete.sh | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/tools/pve/lxc-delete.sh b/tools/pve/lxc-delete.sh index cb413f33..85487cd2 100644 --- a/tools/pve/lxc-delete.sh +++ b/tools/pve/lxc-delete.sh @@ -44,10 +44,10 @@ if ! whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC De echo -e "${RD}Aborted by user.${CL}" exit 0 fi -NODE=$(hostname) -containers=$(pct list | tail -n +2 | awk '{print $0 " " $4}') -if [ -z "$containers" ]; then +mapfile -t containers < <(pct list | tail -n +2) + +if [ ${#containers[@]} -eq 0 ]; then whiptail --title "LXC Container Delete" --msgbox "No LXC containers available!" 10 60 exit 1 fi @@ -55,41 +55,39 @@ fi menu_items=("ALL" "Delete ALL containers" "OFF") FORMAT="%-10s %-10s %-10s %-10s" -while read -r container; do - container_id=$(echo $container | awk '{print $1}') - container_name=$(echo $container | awk '{print $2}') - container_status=$(echo $container | awk '{print $3}') - container_os=$(echo $container | awk '{print $4}') - protected=$(pct config $container_id | grep -i '^protection:' | awk '{print $2}') +for line in "${containers[@]}"; do + container_id=$(echo "$line" | awk '{print $1}') + container_name=$(echo "$line" | awk '{print $2}') + container_status=$(echo "$line" | awk '{print $3}') + container_os=$(echo "$line" | awk '{print $4}') + protected=$(pct config "$container_id" | awk '/^protection:/ {print $2}') is_protected="No" [[ "$protected" == "1" ]] && is_protected="Yes" formatted_line=$(printf "$FORMAT" "$container_name" "$container_status" "$container_os" "$is_protected") menu_items+=("$container_id" "$formatted_line" "OFF") -done < <(printf '%s\n' "$containers") +done CHOICES=$(whiptail --title "LXC Container Delete" \ --checklist "Select LXC containers to delete:\n\nNAME STATUS OS PROTECTED" 25 70 15 \ "${menu_items[@]}" 3>&2 2>&1 1>&3) if [ -z "$CHOICES" ]; then - whiptail --title "LXC Container Delete" \ - --msgbox "No containers selected!" 10 60 + whiptail --title "LXC Container Delete" --msgbox "No containers selected!" 10 60 exit 1 fi read -p "Delete containers manually or automatically? (Default: manual) m/a: " DELETE_MODE DELETE_MODE=${DELETE_MODE:-m} - selected_ids=$(echo "$CHOICES" | tr -d '"' | tr -s ' ' '\n') -# Wenn ALL ausgewählt ist, überschreiben +# ALL ausgewählt if echo "$selected_ids" | grep -q "^ALL$"; then - selected_ids=$(echo "$containers" | awk '{print $1}') + selected_ids=$(printf '%s\n' "${containers[@]}" | awk '{print $1}') fi for container_id in $selected_ids; do status=$(pct status "$container_id") - protected=$(pct config "$container_id" | grep -i '^protection:' | awk '{print $2}') + protected=$(pct config "$container_id" | awk '/^protection:/ {print $2}') is_protected="No" [[ "$protected" == "1" ]] && is_protected="Yes" @@ -98,7 +96,7 @@ for container_id in $selected_ids; do continue fi - if [ "$status" == "status: running" ]; then + if [[ "$status" == "status: running" ]]; then if [[ "$is_protected" == "Yes" && "$DELETE_MODE" == "m" ]]; then read -p "⚠️ Container $container_id is PROTECTED. Delete anyway? (y/N): " CONFIRM_PROTECTED [[ ! "$CONFIRM_PROTECTED" =~ ^[Yy]$ ]] && { From aa4fe70d6c22b13fc78ab5ca194044534a663382 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:16:36 +0200 Subject: [PATCH 067/463] ffmpeg --- misc/tools.func | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/misc/tools.func b/misc/tools.func index 2b4b5769..fe0b752f 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1611,3 +1611,116 @@ function setup_imagemagick() { ensure_usr_local_bin_persist msg_ok "Setup ImageMagick $VERSION" } + +# ------------------------------------------------------------------------------ +# Installs FFmpeg from source or prebuilt binary (Debian/Ubuntu only). +# +# Description: +# - Downloads and builds FFmpeg from GitHub (https://github.com/FFmpeg/FFmpeg) +# - Supports specific version override via FFMPEG_VERSION (e.g. n7.1.1) +# - Supports build profile via FFMPEG_TYPE: +# - minimal : x264, vpx, mp3 only +# - medium : adds subtitles, fonts, opus, vorbis +# - full : adds dav1d, svt-av1, zlib, numa +# - binary : downloads static build (johnvansickle.com) +# - Defaults to latest stable version and full feature set +# +# Notes: +# - Requires: curl, jq, build-essential, and matching codec libraries +# - Result is installed to /usr/local/bin/ffmpeg +# ------------------------------------------------------------------------------ + +function setup_ffmpeg() { + local TMP_DIR + TMP_DIR=$(mktemp -d) + local GITHUB_REPO="FFmpeg/FFmpeg" + local VERSION="${FFMPEG_VERSION:-}" + local TYPE="${FFMPEG_TYPE:-full}" + local BIN_PATH="/usr/local/bin/ffmpeg" + + # Binary fallback mode + if [[ "$TYPE" == "binary" ]]; then + msg_info "Installing FFmpeg (static binary)" + curl -fsSL https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz -o "$TMP_DIR/ffmpeg.tar.xz" + tar -xf "$TMP_DIR/ffmpeg.tar.xz" -C "$TMP_DIR" + local EXTRACTED_DIR + EXTRACTED_DIR=$(find "$TMP_DIR" -maxdepth 1 -type d -name "ffmpeg-*") + cp "$EXTRACTED_DIR/ffmpeg" "$BIN_PATH" + cp "$EXTRACTED_DIR/ffprobe" /usr/local/bin/ffprobe + chmod +x "$BIN_PATH" /usr/local/bin/ffprobe + rm -rf "$TMP_DIR" + msg_ok "Installed FFmpeg binary ($($BIN_PATH -version | head -n1))" + return + fi + + # Auto-detect latest stable version if none specified + if [[ -z "$VERSION" ]]; then + msg_info "Fetching latest stable FFmpeg tag" + VERSION=$(curl -fsSL "https://api.github.com/repos/${GITHUB_REPO}/tags" | + jq -r '.[].name' | + grep -E '^n[0-9]+\.[0-9]+\.[0-9]+$' | # stable only + sort -V | tail -n1) + fi + + if [[ -z "$VERSION" ]]; then + msg_error "Could not determine FFmpeg version" + rm -rf "$TMP_DIR" + return 1 + fi + + msg_info "Installing FFmpeg ${VERSION} ($TYPE)" + + # Dependency selection + local DEPS=(build-essential yasm nasm pkg-config) + case "$TYPE" in + minimal) + DEPS+=(libx264-dev libvpx-dev libmp3lame-dev) + ;; + medium) + DEPS+=(libx264-dev libvpx-dev libmp3lame-dev libfreetype6-dev libass-dev libopus-dev libvorbis-dev) + ;; + full) + DEPS+=( + libx264-dev libx265-dev libvpx-dev libmp3lame-dev + libfreetype6-dev libass-dev libopus-dev libvorbis-dev + libdav1d-dev libsvtav1-dev zlib1g-dev libnuma-dev + ) + ;; + *) + msg_error "Invalid FFMPEG_TYPE: $TYPE" + rm -rf "$TMP_DIR" + return 1 + ;; + esac + + $STD apt-get update + $STD apt-get install -y "${DEPS[@]}" + + curl -fsSL "https://github.com/${GITHUB_REPO}/archive/refs/tags/${VERSION}.tar.gz" -o "$TMP_DIR/ffmpeg.tar.gz" + tar -xzf "$TMP_DIR/ffmpeg.tar.gz" -C "$TMP_DIR" + cd "$TMP_DIR/FFmpeg-"* || { + msg_error "Source extraction failed" + rm -rf "$TMP_DIR" + return 1 + } + + ./configure --enable-gpl --enable-nonfree --disable-static \ + --enable-libx264 --enable-libvpx --enable-libmp3lame \ + $([[ "$TYPE" != "minimal" ]] && echo "--enable-libfreetype --enable-libass --enable-libopus --enable-libvorbis") \ + $([[ "$TYPE" == "full" ]] && echo "--enable-libx265 --enable-libdav1d --enable-libsvtav1 --enable-zlib --enable-libnuma") >/dev/null + + $STD make -j"$(nproc)" + $STD make install + + if ! command -v ffmpeg &>/dev/null; then + msg_error "FFmpeg installation failed" + rm -rf "$TMP_DIR" + return 1 + fi + + local FINAL_VERSION + FINAL_VERSION=$(ffmpeg -version | head -n1 | awk '{print $3}') + rm -rf "$TMP_DIR" + ensure_usr_local_bin_persist + msg_ok "Setup FFmpeg $FINAL_VERSION" +} From 8154a05f6f50e4aa07a6f90ef8c25d82617a368f Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:17:16 +0200 Subject: [PATCH 068/463] Update debian-install.sh --- install/debian-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/debian-install.sh b/install/debian-install.sh index 052fd10f..5d44a0be 100644 --- a/install/debian-install.sh +++ b/install/debian-install.sh @@ -17,6 +17,8 @@ msg_info "Installing Dependencies" $STD apt-get install -y gpg msg_ok "Installed Dependencies" +FFMPEG_VERSION="n7.1.1" FFMPEG_TYPE="full" setup_ffmpeg + #fetch_and_deploy_gh_release "argus" "release-argus/Argus" "singlefile" "latest" "/opt/argus" "Argus-.*linux-amd64" #fetch_and_deploy_gh_release "planka" "plankanban/planka" "prebuild" "latest" "/opt/planka" "planka-prebuild.zip" From 6d48402ab200fa864990a2080d24514f8da1c7d2 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:24:03 +0200 Subject: [PATCH 069/463] Update tools.func --- misc/tools.func | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index fe0b752f..2ff0ba01 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1704,10 +1704,24 @@ function setup_ffmpeg() { return 1 } - ./configure --enable-gpl --enable-nonfree --disable-static \ - --enable-libx264 --enable-libvpx --enable-libmp3lame \ - $([[ "$TYPE" != "minimal" ]] && echo "--enable-libfreetype --enable-libass --enable-libopus --enable-libvorbis") \ - $([[ "$TYPE" == "full" ]] && echo "--enable-libx265 --enable-libdav1d --enable-libsvtav1 --enable-zlib --enable-libnuma") >/dev/null + local args=( + --enable-gpl + --enable-nonfree + --disable-static + --enable-libx264 + --enable-libvpx + --enable-libmp3lame + ) + + if [[ "$TYPE" != "minimal" ]]; then + args+=(--enable-libfreetype --enable-libass --enable-libopus --enable-libvorbis) + fi + + if [[ "$TYPE" == "full" ]]; then + args+=(--enable-libx265 --enable-libdav1d --enable-libsvtav1 --enable-zlib --enable-libnuma) + fi + + ./configure "${args[@]}" >/dev/null $STD make -j"$(nproc)" $STD make install From c293917b6617e52bec6bfca625fbdf3ff8e55e08 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:29:43 +0200 Subject: [PATCH 070/463] Update tools.func --- misc/tools.func | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/misc/tools.func b/misc/tools.func index 2ff0ba01..6253f0ab 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1721,7 +1721,18 @@ function setup_ffmpeg() { args+=(--enable-libx265 --enable-libdav1d --enable-libsvtav1 --enable-zlib --enable-libnuma) fi - ./configure "${args[@]}" >/dev/null + if [[ ${#args[@]} -eq 0 ]]; then + msg_error "FFmpeg configure args array is empty – aborting." + rm -rf "$TMP_DIR" + return 1 + fi + + ./configure "${args[@]}" >"$TMP_DIR/configure.log" 2>&1 || { + msg_error "FFmpeg ./configure failed (see $TMP_DIR/configure.log)" + cat "$TMP_DIR/configure.log" | tail -n 20 + rm -rf "$TMP_DIR" + return 1 + } $STD make -j"$(nproc)" $STD make install From 4e9479377d56732dd9b6c4362991ebf0329de17a Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 12:39:47 +0000 Subject: [PATCH 071/463] Update versions.json (#653) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 121 ++++++++++++++--------------- 1 file changed, 58 insertions(+), 63 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 9c49b72a..bdf49520 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,19 +1,69 @@ [ { "name": "rcourtman/Pulse", - "version": "v3.32.0", - "date": "2025-06-25T22:27:01Z" + "version": "v3.33.1", + "date": "2025-06-30T11:29:32Z" }, { - "name": "sysadminsmedia/homebox", - "version": "v0.20.0", - "date": "2025-06-29T18:50:03Z" + "name": "Graylog2/graylog2-server", + "version": "6.3.0", + "date": "2025-06-30T11:26:45Z" + }, + { + "name": "grokability/snipe-it", + "version": "v8.1.17", + "date": "2025-06-30T11:26:27Z" + }, + { + "name": "prometheus/prometheus", + "version": "v2.53.5", + "date": "2025-06-30T11:01:12Z" + }, + { + "name": "documenso/documenso", + "version": "v1.12.0-rc.8", + "date": "2025-06-30T09:47:37Z" + }, + { + "name": "PrivateBin/PrivateBin", + "version": "1.7.8", + "date": "2025-06-30T09:00:54Z" + }, + { + "name": "fuma-nama/fumadocs", + "version": "fumadocs-mdx@11.6.10", + "date": "2025-06-30T07:07:36Z" + }, + { + "name": "mattermost/mattermost", + "version": "preview-v0.1", + "date": "2025-06-27T14:35:47Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2097", + "date": "2025-06-30T05:53:30Z" + }, + { + "name": "typesense/typesense", + "version": "v29.0", + "date": "2025-06-30T03:52:33Z" }, { "name": "firefly-iii/firefly-iii", "version": "v6.2.19", "date": "2025-06-28T06:53:45Z" }, + { + "name": "keycloak/keycloak", + "version": "26.2.5", + "date": "2025-05-28T06:49:43Z" + }, + { + "name": "sysadminsmedia/homebox", + "version": "v0.20.0", + "date": "2025-06-29T18:50:03Z" + }, { "name": "dgtlmoon/changedetection.io", "version": "0.50.5", @@ -24,11 +74,6 @@ "version": "e5.9.1-rc.1", "date": "2025-06-29T07:27:21Z" }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2084", - "date": "2025-06-29T05:53:38Z" - }, { "name": "theonedev/onedev", "version": "v11.11.2", @@ -39,11 +84,6 @@ "version": "2025.6.3", "date": "2025-06-24T13:00:12Z" }, - { - "name": "PrivateBin/PrivateBin", - "version": "1.7.7", - "date": "2025-06-28T19:57:56Z" - }, { "name": "linkwarden/linkwarden", "version": "v2.11.2", @@ -54,11 +94,6 @@ "version": "v1.22.5", "date": "2025-06-28T16:06:19Z" }, - { - "name": "keycloak/keycloak", - "version": "26.2.5", - "date": "2025-05-28T06:49:43Z" - }, { "name": "Luligu/matterbridge", "version": "3.1.0", @@ -91,14 +126,9 @@ }, { "name": "ollama/ollama", - "version": "v0.9.4-rc1", + "version": "v0.9.4-rc2", "date": "2025-06-27T18:45:33Z" }, - { - "name": "mattermost/mattermost", - "version": "preview-v0.1", - "date": "2025-06-27T14:35:47Z" - }, { "name": "goauthentik/authentik", "version": "version/2025.6.3", @@ -109,11 +139,6 @@ "version": "v1.70.2", "date": "2025-06-27T13:21:17Z" }, - { - "name": "documenso/documenso", - "version": "v1.12.0-rc.7", - "date": "2025-06-27T12:17:45Z" - }, { "name": "sabnzbd/sabnzbd", "version": "4.5.1", @@ -144,11 +169,6 @@ "version": "4.9.1.2", "date": "2025-06-26T22:08:00Z" }, - { - "name": "prometheus/prometheus", - "version": "v3.4.2", - "date": "2025-06-26T21:45:21Z" - }, { "name": "home-assistant/operating-system", "version": "15.2", @@ -169,11 +189,6 @@ "version": "v1.84.3", "date": "2025-06-26T16:31:57Z" }, - { - "name": "fuma-nama/fumadocs", - "version": "fumadocs-ui@15.5.5", - "date": "2025-06-26T15:54:17Z" - }, { "name": "traefik/traefik", "version": "v3.5.0-rc1", @@ -296,19 +311,14 @@ }, { "name": "runtipi/runtipi", - "version": "nightly", - "date": "2025-06-23T19:10:33Z" + "version": "v4.2.1", + "date": "2025-06-03T20:04:28Z" }, { "name": "VictoriaMetrics/VictoriaMetrics", "version": "pmm-6401-v1.120.0", "date": "2025-06-23T15:12:12Z" }, - { - "name": "Graylog2/graylog2-server", - "version": "6.3.0-rc.2", - "date": "2025-06-23T11:31:38Z" - }, { "name": "gotson/komga", "version": "1.22.0", @@ -453,20 +463,5 @@ "name": "cross-seed/cross-seed", "version": "v6.12.7", "date": "2025-06-18T03:44:24Z" - }, - { - "name": "grafana/grafana", - "version": "v11.5.6", - "date": "2025-06-17T22:00:40Z" - }, - { - "name": "project-zot/zot", - "version": "v2.1.5", - "date": "2025-06-17T18:04:11Z" - }, - { - "name": "BookStackApp/BookStack", - "version": "v25.05.1", - "date": "2025-06-17T14:38:04Z" } ] From e0c9e39a58b54e79881915cf78c586f9ae7bcdba Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:45:47 +0200 Subject: [PATCH 072/463] Update tools.func --- misc/tools.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/tools.func b/misc/tools.func index 6253f0ab..705d1c37 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1718,7 +1718,7 @@ function setup_ffmpeg() { fi if [[ "$TYPE" == "full" ]]; then - args+=(--enable-libx265 --enable-libdav1d --enable-libsvtav1 --enable-zlib --enable-libnuma) + args+=(--enable-libx265 --enable-libdav1d --enable-libsvtav1 --enable-zlib) fi if [[ ${#args[@]} -eq 0 ]]; then From ddd3d337fd5163c6c64d40fdc7f6108c67f43503 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:56:23 +0200 Subject: [PATCH 073/463] Update tools.func --- misc/tools.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/tools.func b/misc/tools.func index 705d1c37..6bacfeec 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1706,6 +1706,7 @@ function setup_ffmpeg() { local args=( --enable-gpl + --enable-shared --enable-nonfree --disable-static --enable-libx264 From 03a2ca1e3c1ad7fc9dcc15795e5660ffed7531b5 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:59:48 +0200 Subject: [PATCH 074/463] Update create_lxc.sh --- misc/create_lxc.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 5874ac69..10592a92 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -265,15 +265,11 @@ PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) # Secure creation of the LXC container with lock and template check lockfile="/tmp/template.${TEMPLATE}.lock" -exec 9>"$lockfile" >/dev/null 2>&1 || { - msg_error "Failed to create lock file '$lockfile'." - exit 200 -} +exec 9>"$lockfile" flock -w 60 9 || { msg_error "Timeout while waiting for template lock" exit 211 } - msg_info "Creating LXC Container" if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then msg_error "Container creation failed. Checking if template is corrupted or incomplete." From e03d90c53e2a6172b9afa2808dc9b920574234fc Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:05:12 +0200 Subject: [PATCH 075/463] Update alpine-syncthing-install.sh --- install/alpine-syncthing-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/alpine-syncthing-install.sh b/install/alpine-syncthing-install.sh index 701c052f..60c25a88 100644 --- a/install/alpine-syncthing-install.sh +++ b/install/alpine-syncthing-install.sh @@ -15,6 +15,7 @@ update_os msg_info "Setup Syncthing" $STD apk add --no-cache syncthing +sed -i "{s/127.0.0.1:8384/0.0.0.0:8384/g}" /var/lib/syncthing/.local/state/syncthing/config.xml msg_ok "Setup Syncthing" msg_info "Enabling Syncthing Service" From ac646dbd27a7e36e3cdb822ff4b466629d81f2aa Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:07:09 +0200 Subject: [PATCH 076/463] Update create_lxc.sh --- misc/create_lxc.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 10592a92..5874ac69 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -265,11 +265,15 @@ PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) # Secure creation of the LXC container with lock and template check lockfile="/tmp/template.${TEMPLATE}.lock" -exec 9>"$lockfile" +exec 9>"$lockfile" >/dev/null 2>&1 || { + msg_error "Failed to create lock file '$lockfile'." + exit 200 +} flock -w 60 9 || { msg_error "Timeout while waiting for template lock" exit 211 } + msg_info "Creating LXC Container" if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then msg_error "Container creation failed. Checking if template is corrupted or incomplete." From cd0e6c5293e8615f11a69e21a854d61fc3ba2db3 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:09:15 +0200 Subject: [PATCH 077/463] Update tools.func --- misc/tools.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/tools.func b/misc/tools.func index 6bacfeec..f1419a3f 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1719,7 +1719,7 @@ function setup_ffmpeg() { fi if [[ "$TYPE" == "full" ]]; then - args+=(--enable-libx265 --enable-libdav1d --enable-libsvtav1 --enable-zlib) + args+=(--enable-libx265 --enable-libdav1d --enable-zlib) fi if [[ ${#args[@]} -eq 0 ]]; then From 3bcca9b22e37d856b38084025b05d548065fe937 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:16:30 +0200 Subject: [PATCH 078/463] Update kapowarr.sh --- ct/kapowarr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/kapowarr.sh b/ct/kapowarr.sh index ef1391c7..47bad882 100644 --- a/ct/kapowarr.sh +++ b/ct/kapowarr.sh @@ -38,8 +38,8 @@ function update_script() { mv /opt/kapowarr/db /opt/ msg_ok "Backup Created" - msg_info "Updating $APP to ${RELEASE}" fetch_and_deploy_gh_release "kapowarr" "Casvt/Kapowarr" + msg_info "Updating $APP to ${RELEASE}" mv /opt/db /opt/kapowarr msg_ok "Updated $APP to ${RELEASE}" From faaee25a3ef32b3825c6777eaf1f24c295d0615b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:32:22 +0200 Subject: [PATCH 079/463] ref --- ct/npmplus.sh | 58 ------------------------------------- install/wallabag-install.sh | 56 ++++++++++++++++------------------- 2 files changed, 25 insertions(+), 89 deletions(-) delete mode 100644 ct/npmplus.sh diff --git a/ct/npmplus.sh b/ct/npmplus.sh deleted file mode 100644 index 9e3b0917..00000000 --- a/ct/npmplus.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2025 community-scripts ORG -# Author: MickLesk (CanbiZ) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/ZoeyVid/NPMplus - -APP="NPMplus" -var_tags="${var_tags:-proxy;nginx}" -var_cpu="${var_cpu:-1}" -var_ram="${var_ram:-512}" -var_disk="${var_disk:-3}" -var_os="${var_os:-alpine}" -var_version="${var_version:-3.21}" -var_unprivileged="${var_unprivileged:-1}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE MODE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 14 60 2 \ - "1" "Check for Alpine Updates" OFF \ - "2" "Update NPMplus Docker Container" ON \ - 3>&1 1>&2 2>&3) - - header_info "$APP" - - case "$UPD" in - "1") - msg_info "Updating Alpine OS" - $STD apk -U upgrade - msg_ok "System updated" - exit - ;; - "2") - msg_info "Updating NPMplus Container" - cd /opt - msg_info "Pulling latest container image" - $STD docker compose pull - msg_info "Recreating container" - $STD docker compose up -d - msg_ok "NPMplus container updated" - exit - ;; - esac - exit 0 -} - -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}:81${CL}" diff --git a/install/wallabag-install.sh b/install/wallabag-install.sh index b9f1c5d7..351e8537 100644 --- a/install/wallabag-install.sh +++ b/install/wallabag-install.sh @@ -14,52 +14,46 @@ update_os msg_info "Installing Dependencies (Patience)" $STD apt-get install -y \ - curl \ - git \ - unzip \ - sudo \ - make \ - php8.2 \ - php8.2-{cli,common,bcmath,intl,fpm,tidy,xml,mysql,mbstring,zip,gd,curl} \ - composer \ - apache2 \ - libapache2-mod-php \ - redis \ - mariadb-server + make \ + apache2 \ + libapache2-mod-php \ + redis msg_ok "Installed Dependencies" +setup_mariadb +PHP_VERSION="8.3" PHP_APACHE="YES" PHP_FPM="YES" PHP_MODULE="bcmath,bz2,cli,exif,common,curl,tidy,fpm,gd,intl,mbstring,xml,mysql,zip" setup_php +setup_composer + msg_info "Setting up Database" DB_NAME=wallabag_db DB_USER=wallabag DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) SECRET_KEY="$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32)" -$STD mysql -u root -e "CREATE DATABASE $DB_NAME;" -$STD mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" -$STD mysql -u root -e "GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" +$STD mariadb -u root -e "CREATE DATABASE $DB_NAME;" +$STD mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" +$STD mariadb -u root -e "GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" { - echo "Wallabag Credentials" - echo "Database User: $DB_USER" - echo "Database Password: $DB_PASS" - echo "Database Name: $DB_NAME" -} >> ~/wallabag.creds + echo "Wallabag Credentials" + echo "Database User: $DB_USER" + echo "Database Password: $DB_PASS" + echo "Database Name: $DB_NAME" +} >>~/wallabag.creds msg_ok "Set up Database" +fetch_and_deploy_gh_release "wallabag" "wallabag/wallabag" "prebuild" "latest" "/opt/wallabag" "wallabag-*.tar.gz" + msg_info "Installing Wallabag (Patience)" -RELEASE=$(curl -s https://api.github.com/repos/wallabag/wallabag/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -wget -q "https://github.com/wallabag/wallabag/archive/refs/tags/${RELEASE}.zip" -unzip -q ${RELEASE}.zip -mv wallabag-${RELEASE} /opt/wallabag cd /opt/wallabag useradd -d /opt/wallabag -s /bin/bash -M wallabag chown -R wallabag:wallabag /opt/wallabag mv /opt/wallabag/app/config/parameters.yml.dist /opt/wallabag/app/config/parameters.yml sed -i \ - -e 's|database_name: wallabag|database_name: wallabag_db|' \ - -e 's|database_port: ~|database_port: 3306|' \ - -e 's|database_user: root|database_user: wallabag|' \ - -e 's|database_password: ~|database_password: '"$DB_PASS"'|' \ - -e 's|secret: .*|secret: '"$SECRET_KEY"'|' \ - /opt/wallabag/app/config/parameters.yml + -e 's|database_name: wallabag|database_name: wallabag_db|' \ + -e 's|database_port: ~|database_port: 3306|' \ + -e 's|database_user: root|database_user: wallabag|' \ + -e 's|database_password: ~|database_password: '"$DB_PASS"'|' \ + -e 's|secret: .*|secret: '"$SECRET_KEY"'|' \ + /opt/wallabag/app/config/parameters.yml export COMPOSER_ALLOW_SUPERUSER=1 sudo -u wallabag make install --no-interaction @@ -72,7 +66,7 @@ msg_info "Setting up Virtual Host" cat </etc/nginx/conf.d/wallabag.conf server { root /opt/wallabag/web; - server_name $IPADDRESS; + server_name $IPADDRESS; location / { # try to serve file directly, fallback to app.php From 85e336d93909581c69e9db07c0d1e8ec47df1186 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:32:57 +0000 Subject: [PATCH 080/463] Update .app files (#654) Co-authored-by: GitHub Actions --- ct/headers/npmplus | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 ct/headers/npmplus diff --git a/ct/headers/npmplus b/ct/headers/npmplus deleted file mode 100644 index 9920f297..00000000 --- a/ct/headers/npmplus +++ /dev/null @@ -1,6 +0,0 @@ - _ ______ __ ___ __ - / | / / __ \/ |/ /___ / /_ _______ - / |/ / /_/ / /|_/ / __ \/ / / / / ___/ - / /| / ____/ / / / /_/ / / /_/ (__ ) -/_/ |_/_/ /_/ /_/ .___/_/\__,_/____/ - /_/ From 87cc6138d99469ed97f88c58db57f628f5e81b6c Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:37:43 +0200 Subject: [PATCH 081/463] remove --- ct/alpine-syncthing.sh | 45 ----------------------------- install/alpine-syncthing-install.sh | 30 ------------------- 2 files changed, 75 deletions(-) delete mode 100644 ct/alpine-syncthing.sh delete mode 100644 install/alpine-syncthing-install.sh diff --git a/ct/alpine-syncthing.sh b/ct/alpine-syncthing.sh deleted file mode 100644 index 97f2f226..00000000 --- a/ct/alpine-syncthing.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash -source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) -# Copyright (c) 2021-2025 community-scripts ORG -# Author: MickLesk (CanbiZ) -# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE -# Source: https://syncthing.net/ - -APP="Alpine-Syncthing" -var_tags="${var_tags:-alpine;networking}" -var_cpu="${var_cpu:-1}" -var_ram="${var_ram:-256}" -var_disk="${var_disk:-1}" -var_os="${var_os:-alpine}" -var_version="${var_version:-3.21}" -var_unprivileged="${var_unprivileged:-1}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - msg_info "Updating Alpine Packages" - $STD apk -U upgrade - msg_ok "Updated Alpine Packages" - - msg_info "Updating Syncthing" - $STD apk upgrade syncthing - msg_ok "Updated Syncthing" - - msg_info "Restarting Syncthing" - $STD rc-service syncthing restart - msg_ok "Restarted Syncthing" - - exit 1 -} - -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}:8384${CL}" diff --git a/install/alpine-syncthing-install.sh b/install/alpine-syncthing-install.sh deleted file mode 100644 index 60c25a88..00000000 --- a/install/alpine-syncthing-install.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 community-scripts ORG -# Author: MickLesk (CanbiZ) -# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE -# Source: https://syncthing.net/ - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Setup Syncthing" -$STD apk add --no-cache syncthing -sed -i "{s/127.0.0.1:8384/0.0.0.0:8384/g}" /var/lib/syncthing/.local/state/syncthing/config.xml -msg_ok "Setup Syncthing" - -msg_info "Enabling Syncthing Service" -$STD rc-update add syncthing default -msg_ok "Enabled Syncthing Service" - -msg_info "Starting Syncthing" -$STD rc-service syncthing start -msg_ok "Started Syncthing" - -motd_ssh -customize From bb92be993024193e6423f59fb6599a7d8dc66fe8 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:38:17 +0000 Subject: [PATCH 082/463] Update .app files (#655) Co-authored-by: GitHub Actions --- ct/headers/alpine-syncthing | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 ct/headers/alpine-syncthing diff --git a/ct/headers/alpine-syncthing b/ct/headers/alpine-syncthing deleted file mode 100644 index 8d684d61..00000000 --- a/ct/headers/alpine-syncthing +++ /dev/null @@ -1,6 +0,0 @@ - ___ __ _ _____ __ __ _ - / | / /___ (_)___ ___ / ___/__ ______ _____/ /_/ /_ (_)___ ____ _ - / /| | / / __ \/ / __ \/ _ \______\__ \/ / / / __ \/ ___/ __/ __ \/ / __ \/ __ `/ - / ___ |/ / /_/ / / / / / __/_____/__/ / /_/ / / / / /__/ /_/ / / / / / / / /_/ / -/_/ |_/_/ .___/_/_/ /_/\___/ /____/\__, /_/ /_/\___/\__/_/ /_/_/_/ /_/\__, / - /_/ /____/ /____/ From 68215fde79a4c9fc6e2d6c3427dfb498f9259777 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:44:38 +0200 Subject: [PATCH 083/463] fixes --- ct/jellyfin.sh | 45 ------------------------------ ct/librespeed-rust.sh | 18 +++--------- install/librespeed-rust-install.sh | 17 ++--------- 3 files changed, 6 insertions(+), 74 deletions(-) delete mode 100644 ct/jellyfin.sh diff --git a/ct/jellyfin.sh b/ct/jellyfin.sh deleted file mode 100644 index a7763ead..00000000 --- a/ct/jellyfin.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2025 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://jellyfin.org/ - -APP="Jellyfin" -var_tags="${var_tags:-media}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-2048}" -var_disk="${var_disk:-8}" -var_os="${var_os:-ubuntu}" -var_version="${var_version:-24.04}" -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 /usr/lib/jellyfin ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - msg_info "Updating ${APP} LXC" - $STD apt-get update - $STD apt-get -y upgrade - $STD apt-get -y --with-new-pkgs upgrade jellyfin jellyfin-server - msg_ok "Updated ${APP} LXC" - 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}:8096${CL}" diff --git a/ct/librespeed-rust.sh b/ct/librespeed-rust.sh index c6664b5c..292971e2 100644 --- a/ct/librespeed-rust.sh +++ b/ct/librespeed-rust.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) # Copyright (c) 2021-2025 community-scripts ORG # Author: Joseph Stubberfield (stubbers) # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://github.com/librespeed/speedtest-rust -APP="Librespeed Rust" +APP="Librespeed-Rust" var_tags="${var_tags:-network}" var_cpu="${var_cpu:-1}" var_ram="${var_ram:-512}" @@ -28,22 +28,12 @@ function update_script() { exit fi RELEASE=$(curl -fsSL https://api.github.com/repos/librespeed/speedtest-rust/releases/latest | grep '"tag_name"' | sed -E 's/.*"tag_name": "v([^"]+).*/\1/') - if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + if [[ "${RELEASE}" != "$(cat ~/.librespeed 2>/dev/null)" ]] || [[ ! -f ~/.librespeed ]]; then msg_info "Stopping Services" systemctl stop librespeed-rs msg_ok "Services Stopped" - msg_info "Updating ${APP} to v${RELEASE}" - $STD apt-get update - $STD apt-get -y upgrade - mv /var/lib/librespeed /var/lib/librespeed-backup - temp_file=$(mktemp) - curl -fsSL "https://github.com/librespeed/speedtest-rust/releases/download/v${RELEASE}/librespeed-rs-x86_64-unknown-linux-gnu.deb" -o "$temp_file" - $STD dpkg -u "$temp_file" - rm -rf "$temp_file" - rm -rf /var/lib/librespeed-backup - echo "${RELEASE}" >/opt/"${APPLICATION}"_version.txt - msg_ok "Updated ${APP}" + fetch_and_deploy_gh_release "librespeed-rust" "librespeed/speedtest-rust" "deb" "latest" "/opt/librespeed-rust" "librespeed-rs-x86_64-unknown-linux-gnu.deb" msg_info "Starting Service" systemctl start librespeed-rs diff --git a/install/librespeed-rust-install.sh b/install/librespeed-rust-install.sh index bdba15c5..f056a4ca 100644 --- a/install/librespeed-rust-install.sh +++ b/install/librespeed-rust-install.sh @@ -5,7 +5,6 @@ # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://github.com/librespeed/speedtest-rust -# Import Functions und Setup source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color verb_ip6 @@ -14,18 +13,8 @@ setting_up_container network_check update_os -# Setup App -msg_info "Setup ${APPLICATION}" -RELEASE=$(curl -fsSL https://api.github.com/repos/librespeed/speedtest-rust/releases/latest | grep '"tag_name"' | sed -E 's/.*"tag_name": "v([^"]+).*/\1/') -curl -fsSL -o "librespeed-rs-x86_64-unknown-linux-gnu.deb" "https://github.com/librespeed/speedtest-rust/releases/download/v${RELEASE}/librespeed-rs-x86_64-unknown-linux-gnu.deb" -$STD dpkg -i "librespeed-rs-x86_64-unknown-linux-gnu.deb" -# -# -# -echo "${RELEASE}" >/opt/"${APPLICATION}"_version.txt -msg_ok "Setup ${APPLICATION}" +fetch_and_deploy_gh_release "librespeed-rust" "librespeed/speedtest-rust" "deb" "latest" "/opt/librespeed-rust" "librespeed-rs-x86_64-unknown-linux-gnu.deb" -# Enable service msg_info "Enabling Service" systemctl enable -q --now speedtest_rs.service msg_ok "Enabled Service" @@ -33,9 +22,7 @@ msg_ok "Enabled Service" motd_ssh customize -# Cleanup msg_info "Cleaning up" -rm -f "librespeed-rs-x86_64-unknown-linux-gnu.deb" $STD apt-get -y autoremove $STD apt-get -y autoclean -msg_ok "Cleaned" \ No newline at end of file +msg_ok "Cleaned" From 17429bd3be4bb8f289064001fc0d0bdebde03cde Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:44:57 +0200 Subject: [PATCH 084/463] Delete jellyfin-install.sh --- install/jellyfin-install.sh | 64 ------------------------------------- 1 file changed, 64 deletions(-) delete mode 100644 install/jellyfin-install.sh diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh deleted file mode 100644 index 1c459305..00000000 --- a/install/jellyfin-install.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://jellyfin.org/ - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Setting Up Hardware Acceleration" -$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} -if [[ "$CTTYPE" == "0" ]]; then - chgrp video /dev/dri - chmod 755 /dev/dri - chmod 660 /dev/dri/* - $STD adduser $(id -u -n) video - $STD adduser $(id -u -n) render -fi -msg_ok "Set Up Hardware Acceleration" - -msg_info "Installing Jellyfin" -VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" -# If the keyring directory is absent, create it -if [[ ! -d /etc/apt/keyrings ]]; then - mkdir -p /etc/apt/keyrings -fi -# Download the repository signing key and install it to the keyring directory -curl -fsSL https://repo.jellyfin.org/jellyfin_team.gpg.key | gpg --dearmor --yes --output /etc/apt/keyrings/jellyfin.gpg -# Install the Deb822 format jellyfin.sources entry -cat </etc/apt/sources.list.d/jellyfin.sources -Types: deb -URIs: https://repo.jellyfin.org/${PCT_OSTYPE} -Suites: ${VERSION} -Components: main -Architectures: amd64 -Signed-By: /etc/apt/keyrings/jellyfin.gpg -EOF -# Install Jellyfin using the metapackage (which will fetch jellyfin-server, jellyfin-web, and jellyfin-ffmpeg5) -$STD apt-get update -$STD apt-get install -y jellyfin -sed -i 's/"MinimumLevel": "Information"/"MinimumLevel": "Error"/g' /etc/jellyfin/logging.json -chown -R jellyfin:adm /etc/jellyfin -sleep 10 -systemctl restart jellyfin -if [[ "$CTTYPE" == "0" ]]; then - sed -i -e 's/^ssl-cert:x:104:$/render:x:104:root,jellyfin/' -e 's/^render:x:108:root,jellyfin$/ssl-cert:x:108:/' /etc/group -else - sed -i -e 's/^ssl-cert:x:104:$/render:x:104:jellyfin/' -e 's/^render:x:108:jellyfin$/ssl-cert:x:108:/' /etc/group -fi -msg_ok "Installed Jellyfin" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" From 56671c47d9735c8f59d15f3db5b2e47edd12ed17 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:45:15 +0000 Subject: [PATCH 085/463] Update .app files (#656) Co-authored-by: GitHub Actions --- ct/headers/jellyfin | 6 ------ ct/headers/librespeed-rust | 12 ++++++------ 2 files changed, 6 insertions(+), 12 deletions(-) delete mode 100644 ct/headers/jellyfin diff --git a/ct/headers/jellyfin b/ct/headers/jellyfin deleted file mode 100644 index d905c4db..00000000 --- a/ct/headers/jellyfin +++ /dev/null @@ -1,6 +0,0 @@ - __ ____ _____ - / /__ / / /_ __/ __(_)___ - __ / / _ \/ / / / / / /_/ / __ \ -/ /_/ / __/ / / /_/ / __/ / / / / -\____/\___/_/_/\__, /_/ /_/_/ /_/ - /____/ diff --git a/ct/headers/librespeed-rust b/ct/headers/librespeed-rust index 0300b747..d032782a 100644 --- a/ct/headers/librespeed-rust +++ b/ct/headers/librespeed-rust @@ -1,6 +1,6 @@ - __ _ __ __ ____ __ - / / (_) /_ ________ _________ ___ ___ ____/ / / __ \__ _______/ /_ - / / / / __ \/ ___/ _ \/ ___/ __ \/ _ \/ _ \/ __ / / /_/ / / / / ___/ __/ - / /___/ / /_/ / / / __(__ ) /_/ / __/ __/ /_/ / / _, _/ /_/ (__ ) /_ -/_____/_/_.___/_/ \___/____/ .___/\___/\___/\__,_/ /_/ |_|\__,_/____/\__/ - /_/ + __ _ __ __ ____ __ + / / (_) /_ ________ _________ ___ ___ ____/ / / __ \__ _______/ /_ + / / / / __ \/ ___/ _ \/ ___/ __ \/ _ \/ _ \/ __ /_____/ /_/ / / / / ___/ __/ + / /___/ / /_/ / / / __(__ ) /_/ / __/ __/ /_/ /_____/ _, _/ /_/ (__ ) /_ +/_____/_/_.___/_/ \___/____/ .___/\___/\___/\__,_/ /_/ |_|\__,_/____/\__/ + /_/ From 45edf6c760a42655b854817c64d9ebcbc506fa1d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:46:07 +0200 Subject: [PATCH 086/463] Update debian-install.sh --- install/debian-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/debian-install.sh b/install/debian-install.sh index 5d44a0be..16287231 100644 --- a/install/debian-install.sh +++ b/install/debian-install.sh @@ -17,7 +17,7 @@ msg_info "Installing Dependencies" $STD apt-get install -y gpg msg_ok "Installed Dependencies" -FFMPEG_VERSION="n7.1.1" FFMPEG_TYPE="full" setup_ffmpeg +#FFMPEG_VERSION="n7.1.1" FFMPEG_TYPE="full" setup_ffmpeg #fetch_and_deploy_gh_release "argus" "release-argus/Argus" "singlefile" "latest" "/opt/argus" "Argus-.*linux-amd64" #fetch_and_deploy_gh_release "planka" "plankanban/planka" "prebuild" "latest" "/opt/planka" "planka-prebuild.zip" From 04ef1ea7db94d3d613c58f7276bbd67ebf2afcbb Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:48:04 +0200 Subject: [PATCH 087/463] binary --- ct/librespeed-rust.sh | 2 +- install/librespeed-rust-install.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/librespeed-rust.sh b/ct/librespeed-rust.sh index 292971e2..74847372 100644 --- a/ct/librespeed-rust.sh +++ b/ct/librespeed-rust.sh @@ -33,7 +33,7 @@ function update_script() { systemctl stop librespeed-rs msg_ok "Services Stopped" - fetch_and_deploy_gh_release "librespeed-rust" "librespeed/speedtest-rust" "deb" "latest" "/opt/librespeed-rust" "librespeed-rs-x86_64-unknown-linux-gnu.deb" + fetch_and_deploy_gh_release "librespeed-rust" "librespeed/speedtest-rust" "binary" "latest" "/opt/librespeed-rust" "librespeed-rs-x86_64-unknown-linux-gnu.deb" msg_info "Starting Service" systemctl start librespeed-rs diff --git a/install/librespeed-rust-install.sh b/install/librespeed-rust-install.sh index f056a4ca..7013543f 100644 --- a/install/librespeed-rust-install.sh +++ b/install/librespeed-rust-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -fetch_and_deploy_gh_release "librespeed-rust" "librespeed/speedtest-rust" "deb" "latest" "/opt/librespeed-rust" "librespeed-rs-x86_64-unknown-linux-gnu.deb" +fetch_and_deploy_gh_release "librespeed-rust" "librespeed/speedtest-rust" "binary" "latest" "/opt/librespeed-rust" "librespeed-rs-x86_64-unknown-linux-gnu.deb" msg_info "Enabling Service" systemctl enable -q --now speedtest_rs.service From ba3bbe4ae8b5cb3f333525c612f2ca8a8cad579b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:48:50 +0200 Subject: [PATCH 088/463] Update librespeed-rust.json --- frontend/public/json/librespeed-rust.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/public/json/librespeed-rust.json b/frontend/public/json/librespeed-rust.json index ce067083..753b408a 100644 --- a/frontend/public/json/librespeed-rust.json +++ b/frontend/public/json/librespeed-rust.json @@ -17,7 +17,7 @@ "install_methods": [ { "type": "default", - "script": "ct/librespeed.sh", + "script": "ct/librespeed-rust.sh", "resources": { "cpu": 1, "ram": 512, From 7dbaa038ee2cfbde0b0f9fa63da7cdc7fa617813 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 30 Jun 2025 16:37:47 +0200 Subject: [PATCH 089/463] Update tools.func --- misc/tools.func | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index f1419a3f..089cef29 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -824,19 +824,30 @@ function fetch_and_deploy_gh_release() { elif [[ "$mode" == "binary" ]]; then local arch arch=$(dpkg --print-architecture 2>/dev/null || uname -m) - [[ "$arch" == "x86_64" ]] && arch="x86_64" + [[ "$arch" == "x86_64" ]] && arch="amd64" [[ "$arch" == "aarch64" ]] && arch="arm64" local assets url_match="" assets=$(echo "$json" | jq -r '.assets[].browser_download_url') - for u in $assets; do - if [[ "$u" =~ ($arch|amd64|x86_64|aarch64|arm64).*\.deb$ ]]; then - url_match="$u" - break - fi - done + # If explicit filename pattern is provided (param $6), match that first + if [[ -n "$6" ]]; then + for u in $assets; do + [[ "$u" =~ $6 || "$u" == *"$6" ]] && url_match="$u" && break + done + fi + # If no match via explicit pattern, fall back to architecture heuristic + if [[ -z "$url_match" ]]; then + for u in $assets; do + if [[ "$u" =~ ($arch|amd64|x86_64|aarch64|arm64).*\.deb$ ]]; then + url_match="$u" + break + fi + done + fi + + # Fallback: any .deb file if [[ -z "$url_match" ]]; then for u in $assets; do [[ "$u" =~ \.deb$ ]] && url_match="$u" && break From 0b8811e18f754eed275d3a51050f4bc59f50d38f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 30 Jun 2025 18:24:48 +0000 Subject: [PATCH 090/463] Deleted files for issue: Kapowarr --- ct/kapowarr.sh | 64 ------------------------------ frontend/public/json/kapowarr.json | 35 ---------------- install/kapowarr-install.sh | 54 ------------------------- 3 files changed, 153 deletions(-) delete mode 100644 ct/kapowarr.sh delete mode 100644 frontend/public/json/kapowarr.json delete mode 100644 install/kapowarr-install.sh diff --git a/ct/kapowarr.sh b/ct/kapowarr.sh deleted file mode 100644 index 47bad882..00000000 --- a/ct/kapowarr.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env bash -source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) -# Copyright (c) 2021-2025 community-scripts ORG -# Author: Slaviša Arežina (tremor021) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/Casvt/Kapowarr - -APP="Kapowarr" -var_tags="${var_tags:-Arr}" -var_cpu="${var_cpu:-1}" -var_ram="${var_ram:-256}" -var_disk="${var_disk:-2}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -var_unprivileged="${var_unprivileged:-1}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - header_info - check_container_storage - check_container_resources - - if [[ ! -f /etc/systemd/system/kapowarr.service ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - RELEASE=$(curl -s https://api.github.com/repos/Casvt/Kapowarr/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - if [[ "${RELEASE}" != "$(cat $HOME/.kapowarr)" ]] || [[ ! -f $HOME/.kapowarr ]]; then - msg_info "Stopping $APP" - systemctl stop kapowarr - msg_ok "Stopped $APP" - - msg_info "Creating Backup" - mv /opt/kapowarr/db /opt/ - msg_ok "Backup Created" - - fetch_and_deploy_gh_release "kapowarr" "Casvt/Kapowarr" - msg_info "Updating $APP to ${RELEASE}" - mv /opt/db /opt/kapowarr - msg_ok "Updated $APP to ${RELEASE}" - - msg_info "Starting $APP" - systemctl start kapowarr - msg_ok "Started $APP" - - msg_ok "Update Successful" - else - msg_ok "No update required. ${APP} is already at ${RELEASE}" - 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}http://${IP}:5656${CL}" diff --git a/frontend/public/json/kapowarr.json b/frontend/public/json/kapowarr.json deleted file mode 100644 index e5d69d07..00000000 --- a/frontend/public/json/kapowarr.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "Kapowarr", - "slug": "kapowarr", - "categories": [ - 14 - ], - "date_created": "2025-06-09", - "type": "ct", - "updateable": true, - "privileged": false, - "interface_port": 5656, - "documentation": "https://casvt.github.io/Kapowarr/general_info/workings/", - "website": "https://casvt.github.io/Kapowarr/", - "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/kapowarr.webp", - "config_path": "", - "description": "Kapowarr allows you to build a digital library of comics. You can add volumes, map them to a folder and start managing! Download, rename, move and convert issues of the volume (including TPB's, One Shots, Hard Covers, and more). The whole process is automated and can be customised in the settings.", - "install_methods": [ - { - "type": "default", - "script": "ct/kapowarr.sh", - "resources": { - "cpu": 1, - "ram": 256, - "hdd": 2, - "os": "debian", - "version": "12" - } - } - ], - "default_credentials": { - "username": null, - "password": null - }, - "notes": [] -} diff --git a/install/kapowarr-install.sh b/install/kapowarr-install.sh deleted file mode 100644 index c5f29a7b..00000000 --- a/install/kapowarr-install.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 community-scripts ORG -# Author: Slaviša Arežina (tremor021) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/Casvt/Kapowarr - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Setup Python3" -$STD apt-get install -y python3-pip -msg_ok "Setup Python3" - -setup_uv -fetch_and_deploy_gh_release "kapowarr" "Casvt/Kapowarr" - -msg_info "Setup Kapowarr" -cd /opt/kapowarr -$STD uv venv .venv -$STD source .venv/bin/activate -$STD uv pip install --upgrade pip -$STD uv pip install --no-cache-dir -r requirements.txt -msg_ok "Installed Kapowarr" - -msg_info "Creating Service" -cat </etc/systemd/system/kapowarr.service -[Unit] -Description=Kapowarr Service -After=network.target - -[Service] -WorkingDirectory=/opt/kapowarr/ -ExecStart=/opt/kapowarr/.venv/bin/python3 Kapowarr.py -Restart=always - -[Install] -WantedBy=multi-user.target -EOF -systemctl enable -q --now kapowarr -msg_ok "Created Service" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" From 82ff859c6d646a1ad6954994ae34ccdcb551fe0c Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 18:29:44 +0000 Subject: [PATCH 091/463] Update .app files (#658) Co-authored-by: GitHub Actions --- ct/headers/kapowarr | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 ct/headers/kapowarr diff --git a/ct/headers/kapowarr b/ct/headers/kapowarr deleted file mode 100644 index e127f364..00000000 --- a/ct/headers/kapowarr +++ /dev/null @@ -1,6 +0,0 @@ - __ __ - / //_/___ _____ ____ _ ______ ___________ - / ,< / __ `/ __ \/ __ \ | /| / / __ `/ ___/ ___/ - / /| / /_/ / /_/ / /_/ / |/ |/ / /_/ / / / / -/_/ |_\__,_/ .___/\____/|__/|__/\__,_/_/ /_/ - /_/ From 8feaf01312c3a71ae3a046bad0f0b3a201782c05 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 01:50:44 +0000 Subject: [PATCH 092/463] Update versions.json (#659) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 104 +++++++++++++++++++---------- 1 file changed, 67 insertions(+), 37 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index bdf49520..9485c6f3 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,9 +1,59 @@ [ + { + "name": "MagicMirrorOrg/MagicMirror", + "version": "v2.32.0", + "date": "2025-06-30T22:12:48Z" + }, + { + "name": "mongodb/mongo", + "version": "r8.0.11", + "date": "2025-06-30T20:30:31Z" + }, + { + "name": "docker/compose", + "version": "v2.38.1", + "date": "2025-06-30T20:07:35Z" + }, + { + "name": "home-assistant/core", + "version": "2025.6.3", + "date": "2025-06-24T13:00:12Z" + }, { "name": "rcourtman/Pulse", "version": "v3.33.1", "date": "2025-06-30T11:29:32Z" }, + { + "name": "jhuckaby/Cronicle", + "version": "v0.9.81", + "date": "2025-06-30T16:40:33Z" + }, + { + "name": "ollama/ollama", + "version": "v0.9.4-rc2", + "date": "2025-06-27T18:45:33Z" + }, + { + "name": "prometheus/prometheus", + "version": "v2.53.5", + "date": "2025-06-30T11:01:12Z" + }, + { + "name": "n8n-io/n8n", + "version": "n8n@1.100.0", + "date": "2025-06-23T12:48:35Z" + }, + { + "name": "jupyter/notebook", + "version": "v7.4.4", + "date": "2025-06-30T13:04:22Z" + }, + { + "name": "keycloak/keycloak", + "version": "26.3.0", + "date": "2025-06-30T12:53:32Z" + }, { "name": "Graylog2/graylog2-server", "version": "6.3.0", @@ -14,11 +64,6 @@ "version": "v8.1.17", "date": "2025-06-30T11:26:27Z" }, - { - "name": "prometheus/prometheus", - "version": "v2.53.5", - "date": "2025-06-30T11:01:12Z" - }, { "name": "documenso/documenso", "version": "v1.12.0-rc.8", @@ -54,11 +99,6 @@ "version": "v6.2.19", "date": "2025-06-28T06:53:45Z" }, - { - "name": "keycloak/keycloak", - "version": "26.2.5", - "date": "2025-05-28T06:49:43Z" - }, { "name": "sysadminsmedia/homebox", "version": "v0.20.0", @@ -79,11 +119,6 @@ "version": "v11.11.2", "date": "2025-06-29T01:40:39Z" }, - { - "name": "home-assistant/core", - "version": "2025.6.3", - "date": "2025-06-24T13:00:12Z" - }, { "name": "linkwarden/linkwarden", "version": "v2.11.2", @@ -124,11 +159,6 @@ "version": "v1.26.0", "date": "2025-06-27T19:15:24Z" }, - { - "name": "ollama/ollama", - "version": "v0.9.4-rc2", - "date": "2025-06-27T18:45:33Z" - }, { "name": "goauthentik/authentik", "version": "version/2025.6.3", @@ -214,11 +244,6 @@ "version": "18.0.7", "date": "2025-06-26T09:16:33Z" }, - { - "name": "mongodb/mongo", - "version": "r8.1.2-rc1", - "date": "2025-06-25T22:42:04Z" - }, { "name": "gristlabs/grist-core", "version": "v1.6.1", @@ -249,11 +274,6 @@ "version": "testing", "date": "2025-06-16T18:10:42Z" }, - { - "name": "n8n-io/n8n", - "version": "n8n@1.100.0", - "date": "2025-06-23T12:48:35Z" - }, { "name": "moghtech/komodo", "version": "v1.18.4", @@ -284,11 +304,6 @@ "version": "v1.132.0", "date": "2025-06-17T13:49:30Z" }, - { - "name": "docker/compose", - "version": "v2.37.3", - "date": "2025-06-24T14:05:33Z" - }, { "name": "Checkmk/checkmk", "version": "v2.4.0p5", @@ -311,8 +326,8 @@ }, { "name": "runtipi/runtipi", - "version": "v4.2.1", - "date": "2025-06-03T20:04:28Z" + "version": "nightly", + "date": "2025-06-23T19:10:33Z" }, { "name": "VictoriaMetrics/VictoriaMetrics", @@ -463,5 +478,20 @@ "name": "cross-seed/cross-seed", "version": "v6.12.7", "date": "2025-06-18T03:44:24Z" + }, + { + "name": "grafana/grafana", + "version": "v11.5.6", + "date": "2025-06-17T22:00:40Z" + }, + { + "name": "project-zot/zot", + "version": "v2.1.5", + "date": "2025-06-17T18:04:11Z" + }, + { + "name": "cloudflare/cloudflared", + "version": "2025.6.1", + "date": "2025-06-17T12:45:39Z" } ] From 907120356ef52ea6dae0661866c8fd3a8d266966 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 11:24:51 +0200 Subject: [PATCH 093/463] Update create_lxc.sh --- misc/create_lxc.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 5874ac69..5b792c6e 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -240,12 +240,18 @@ if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE" || ! zstdcat "$TEMPLAT for attempt in {1..3}; do msg_info "Attempt $attempt: Downloading LXC template..." - if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then + if command -v timeout >/dev/null; then + timeout --foreground 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1 + else + pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1 + fi + + if [[ $? -eq 0 ]]; then msg_ok "Template download successful." break fi - if [ $attempt -eq 3 ]; then + if [[ $attempt -eq 3 ]]; then msg_error "Failed after 3 attempts. Please check your Proxmox host’s internet access or manually run:\n pveam download $TEMPLATE_STORAGE $TEMPLATE" exit 208 fi From 6f4ac74113e16234129b382d4f9bb462b604fc93 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 13:08:39 +0200 Subject: [PATCH 094/463] Update create_lxc.sh --- misc/create_lxc.sh | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 5b792c6e..88820aa8 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -106,23 +106,41 @@ function select_storage() { exit 221 } + # Gather valid storages from /etc/pve/storage.cfg + local -a VALID_STORAGES=() + local CURRENT_STORAGE="" + while read -r LINE; do + if [[ "$LINE" =~ ^(dir|lvm|lvmthin|zfspool|.*):[[:space:]]*(.+)$ ]]; then + CURRENT_STORAGE="${BASH_REMATCH[2]}" + elif [[ "$LINE" =~ ^[[:space:]]*content[[:space:]]*=[[:space:]]*(.+)$ ]]; then + [[ ",${BASH_REMATCH[1]}," =~ ,$CONTENT, ]] && VALID_STORAGES+=("$CURRENT_STORAGE") + fi + done COL_WIDTH)) && COL_WIDTH=${#DISPLAY} done < <(pvesm status -content "$CONTENT" | awk 'NR>1') if [ ${#MENU[@]} -eq 0 ]; then - msg_error "No storage found for content type '$CONTENT'." + msg_error "No storage found that supports '${CONTENT}'." exit 203 fi From 98efb802927bdcdd9a8b0e1715554e5fcf47df45 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 13:11:55 +0200 Subject: [PATCH 095/463] Update create_lxc.sh --- misc/create_lxc.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 88820aa8..30121f7c 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -113,7 +113,8 @@ function select_storage() { if [[ "$LINE" =~ ^(dir|lvm|lvmthin|zfspool|.*):[[:space:]]*(.+)$ ]]; then CURRENT_STORAGE="${BASH_REMATCH[2]}" elif [[ "$LINE" =~ ^[[:space:]]*content[[:space:]]*=[[:space:]]*(.+)$ ]]; then - [[ ",${BASH_REMATCH[1]}," =~ ,$CONTENT, ]] && VALID_STORAGES+=("$CURRENT_STORAGE") + local CONTENTS="${BASH_REMATCH[1]}" + [[ ",${CONTENTS}," =~ ,$CONTENT, ]] && VALID_STORAGES+=("$CURRENT_STORAGE") fi done Date: Tue, 1 Jul 2025 13:24:52 +0200 Subject: [PATCH 096/463] Update create_lxc.sh --- misc/create_lxc.sh | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 30121f7c..5874ac69 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -106,42 +106,23 @@ function select_storage() { exit 221 } - # Gather valid storages from /etc/pve/storage.cfg - local -a VALID_STORAGES=() - local CURRENT_STORAGE="" - while read -r LINE; do - if [[ "$LINE" =~ ^(dir|lvm|lvmthin|zfspool|.*):[[:space:]]*(.+)$ ]]; then - CURRENT_STORAGE="${BASH_REMATCH[2]}" - elif [[ "$LINE" =~ ^[[:space:]]*content[[:space:]]*=[[:space:]]*(.+)$ ]]; then - local CONTENTS="${BASH_REMATCH[1]}" - [[ ",${CONTENTS}," =~ ,$CONTENT, ]] && VALID_STORAGES+=("$CURRENT_STORAGE") - fi - done COL_WIDTH)) && COL_WIDTH=${#DISPLAY} done < <(pvesm status -content "$CONTENT" | awk 'NR>1') if [ ${#MENU[@]} -eq 0 ]; then - msg_error "No storage found that supports '${CONTENT}'." + msg_error "No storage found for content type '$CONTENT'." exit 203 fi @@ -259,18 +240,12 @@ if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE" || ! zstdcat "$TEMPLAT for attempt in {1..3}; do msg_info "Attempt $attempt: Downloading LXC template..." - if command -v timeout >/dev/null; then - timeout --foreground 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1 - else - pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1 - fi - - if [[ $? -eq 0 ]]; then + if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then msg_ok "Template download successful." break fi - if [[ $attempt -eq 3 ]]; then + if [ $attempt -eq 3 ]; then msg_error "Failed after 3 attempts. Please check your Proxmox host’s internet access or manually run:\n pveam download $TEMPLATE_STORAGE $TEMPLATE" exit 208 fi From 7384b1f1a252ab877256aee62421d2456c59ca0f Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 13:30:21 +0200 Subject: [PATCH 097/463] Update create_lxc.sh --- misc/create_lxc.sh | 48 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 5874ac69..fdeb0424 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -50,18 +50,54 @@ function on_terminate() { exit 143 } +function check_storage_support() { + local CONTENT="$1" + local -a VALID_STORAGES=() + local TYPE="" NAME="" CONTENTS=() + local CURRENT_NAME="" CURRENT_TYPE="" CURRENT_CONTENTS=() + + while IFS= read -r line || [[ -n "$line" ]]; do + if [[ "$line" =~ ^([a-z0-9]+):[[:space:]]*([a-zA-Z0-9_-]+) ]]; then + [[ -n "$CURRENT_NAME" ]] && { + if [[ " ${CURRENT_CONTENTS[*]} " =~ " $CONTENT " ]]; then + VALID_STORAGES+=("$CURRENT_NAME") + fi + CURRENT_CONTENTS=() + } + CURRENT_TYPE="${BASH_REMATCH[1]}" + CURRENT_NAME="${BASH_REMATCH[2]}" + elif [[ "$line" =~ ^[[:space:]]*content[[:space:]]*[=]?[[:space:]]*(.+)$ ]]; then + IFS=',' read -ra PARTS <<<"${BASH_REMATCH[1]}" + for c in "${PARTS[@]}"; do + CURRENT_CONTENTS+=("$(echo "$c" | xargs)") + done + fi + done 1') -if [ -z "$VALIDCT" ]; then - msg_error "Unable to detect a valid Container Storage location." +if ! check_storage_support "rootdir"; then + msg_error "No valid storage found for 'rootdir' (Container)." exit 1 fi -VALIDTMP=$(pvesm status -content vztmpl | awk 'NR>1') -if [ -z "$VALIDTMP" ]; then - msg_error "Unable to detect a valid Template Storage location." +if ! check_storage_support "vztmpl"; then + msg_error "No valid storage found for 'vztmpl' (Template)." exit 1 fi +msg_ok "Storage types rootdir and vztmpl are supported." # This function is used to select the storage class and determine the corresponding storage content type and label. function select_storage() { From 1e9036acf2b2ae0f972d9fab9994eb096c57c4ab Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 13:32:19 +0200 Subject: [PATCH 098/463] Update create_lxc.sh --- misc/create_lxc.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index fdeb0424..f70803b7 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -57,7 +57,8 @@ function check_storage_support() { local CURRENT_NAME="" CURRENT_TYPE="" CURRENT_CONTENTS=() while IFS= read -r line || [[ -n "$line" ]]; do - if [[ "$line" =~ ^([a-z0-9]+):[[:space:]]*([a-zA-Z0-9_-]+) ]]; then + # Match Speicher-Typ und Name + if [[ "$line" =~ ^(dir|lvm|lvmthin|zfspool):[[:space:]]*([a-zA-Z0-9._-]+) ]]; then [[ -n "$CURRENT_NAME" ]] && { if [[ " ${CURRENT_CONTENTS[*]} " =~ " $CONTENT " ]]; then VALID_STORAGES+=("$CURRENT_NAME") @@ -66,7 +67,11 @@ function check_storage_support() { } CURRENT_TYPE="${BASH_REMATCH[1]}" CURRENT_NAME="${BASH_REMATCH[2]}" - elif [[ "$line" =~ ^[[:space:]]*content[[:space:]]*[=]?[[:space:]]*(.+)$ ]]; then + continue + fi + + # Match content-Zeile + if [[ "$line" =~ ^[[:space:]]*content[[:space:]]*=?[[:space:]]*(.+)$ ]]; then IFS=',' read -ra PARTS <<<"${BASH_REMATCH[1]}" for c in "${PARTS[@]}"; do CURRENT_CONTENTS+=("$(echo "$c" | xargs)") @@ -74,17 +79,14 @@ function check_storage_support() { fi done Date: Tue, 1 Jul 2025 13:35:11 +0200 Subject: [PATCH 099/463] Update create_lxc.sh --- misc/create_lxc.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index f70803b7..910e3df4 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -53,11 +53,9 @@ function on_terminate() { function check_storage_support() { local CONTENT="$1" local -a VALID_STORAGES=() - local TYPE="" NAME="" CONTENTS=() - local CURRENT_NAME="" CURRENT_TYPE="" CURRENT_CONTENTS=() + local CURRENT_NAME="" CURRENT_CONTENTS=() while IFS= read -r line || [[ -n "$line" ]]; do - # Match Speicher-Typ und Name if [[ "$line" =~ ^(dir|lvm|lvmthin|zfspool):[[:space:]]*([a-zA-Z0-9._-]+) ]]; then [[ -n "$CURRENT_NAME" ]] && { if [[ " ${CURRENT_CONTENTS[*]} " =~ " $CONTENT " ]]; then @@ -65,12 +63,10 @@ function check_storage_support() { fi CURRENT_CONTENTS=() } - CURRENT_TYPE="${BASH_REMATCH[1]}" CURRENT_NAME="${BASH_REMATCH[2]}" continue fi - # Match content-Zeile if [[ "$line" =~ ^[[:space:]]*content[[:space:]]*=?[[:space:]]*(.+)$ ]]; then IFS=',' read -ra PARTS <<<"${BASH_REMATCH[1]}" for c in "${PARTS[@]}"; do From 7a7c8ee7160f56a56f58631dd437a42410b67fa9 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 13:38:26 +0200 Subject: [PATCH 100/463] Update create_lxc.sh --- misc/create_lxc.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 910e3df4..f5b7518b 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -56,17 +56,20 @@ function check_storage_support() { local CURRENT_NAME="" CURRENT_CONTENTS=() while IFS= read -r line || [[ -n "$line" ]]; do + # Neuer Block if [[ "$line" =~ ^(dir|lvm|lvmthin|zfspool):[[:space:]]*([a-zA-Z0-9._-]+) ]]; then - [[ -n "$CURRENT_NAME" ]] && { + # Wenn vorheriger Block gültig war, prüfen + if [[ -n "$CURRENT_NAME" && "${#CURRENT_CONTENTS[@]}" -gt 0 ]]; then if [[ " ${CURRENT_CONTENTS[*]} " =~ " $CONTENT " ]]; then VALID_STORAGES+=("$CURRENT_NAME") fi - CURRENT_CONTENTS=() - } + fi CURRENT_NAME="${BASH_REMATCH[2]}" + CURRENT_CONTENTS=() continue fi + # Content-Zeile if [[ "$line" =~ ^[[:space:]]*content[[:space:]]*=?[[:space:]]*(.+)$ ]]; then IFS=',' read -ra PARTS <<<"${BASH_REMATCH[1]}" for c in "${PARTS[@]}"; do @@ -76,7 +79,7 @@ function check_storage_support() { done Date: Tue, 1 Jul 2025 13:45:22 +0200 Subject: [PATCH 101/463] Update create_lxc.sh --- misc/create_lxc.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index f5b7518b..a1918743 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -27,7 +27,7 @@ trap on_terminate TERM function on_exit() { local exit_code="$?" - [[ -n "${lockfile:-}" ]] + [[ -n "${lockfile:-}" && -e "$lockfile" ]] && rm -f "$lockfile" exit "$exit_code" } @@ -56,16 +56,20 @@ function check_storage_support() { local CURRENT_NAME="" CURRENT_CONTENTS=() while IFS= read -r line || [[ -n "$line" ]]; do - # Neuer Block + # Prüfen auf Storage-Typ-Zeile (dir:, lvm:, lvmthin:, zfspool:) if [[ "$line" =~ ^(dir|lvm|lvmthin|zfspool):[[:space:]]*([a-zA-Z0-9._-]+) ]]; then - # Wenn vorheriger Block gültig war, prüfen if [[ -n "$CURRENT_NAME" && "${#CURRENT_CONTENTS[@]}" -gt 0 ]]; then if [[ " ${CURRENT_CONTENTS[*]} " =~ " $CONTENT " ]]; then VALID_STORAGES+=("$CURRENT_NAME") fi fi - CURRENT_NAME="${BASH_REMATCH[2]}" - CURRENT_CONTENTS=() + + # Nur wenn der Regex gematcht hat, darf man auf BASH_REMATCH zugreifen + CURRENT_NAME="" + if [[ ${#BASH_REMATCH[@]} -ge 3 ]]; then + CURRENT_NAME="${BASH_REMATCH[2]}" + CURRENT_CONTENTS=() + fi continue fi From 0129c2df0fd472c5ad692f4d8c0f4fb8e85241a0 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 12:40:16 +0000 Subject: [PATCH 102/463] Update versions.json (#660) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 113 +++++++++++------------------ 1 file changed, 44 insertions(+), 69 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 9485c6f3..35a70510 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,44 @@ [ + { + "name": "syncthing/syncthing", + "version": "v1.30.0", + "date": "2025-07-01T11:29:11Z" + }, + { + "name": "Checkmk/checkmk", + "version": "v2.2.0p44-rc1", + "date": "2025-07-01T11:10:25Z" + }, + { + "name": "keycloak/keycloak", + "version": "26.3.0", + "date": "2025-07-01T10:32:30Z" + }, + { + "name": "rcourtman/Pulse", + "version": "v99.99.99", + "date": "2025-07-01T08:26:41Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2101", + "date": "2025-07-01T05:56:59Z" + }, + { + "name": "zabbix/zabbix", + "version": "7.4.0", + "date": "2025-07-01T04:36:51Z" + }, + { + "name": "openobserve/openobserve", + "version": "v0.15.0-rc3", + "date": "2025-07-01T04:09:37Z" + }, + { + "name": "NginxProxyManager/nginx-proxy-manager", + "version": "v2.12.4", + "date": "2025-07-01T01:45:42Z" + }, { "name": "MagicMirrorOrg/MagicMirror", "version": "v2.32.0", @@ -19,11 +59,6 @@ "version": "2025.6.3", "date": "2025-06-24T13:00:12Z" }, - { - "name": "rcourtman/Pulse", - "version": "v3.33.1", - "date": "2025-06-30T11:29:32Z" - }, { "name": "jhuckaby/Cronicle", "version": "v0.9.81", @@ -31,8 +66,8 @@ }, { "name": "ollama/ollama", - "version": "v0.9.4-rc2", - "date": "2025-06-27T18:45:33Z" + "version": "v0.9.4-rc5", + "date": "2025-06-30T15:59:03Z" }, { "name": "prometheus/prometheus", @@ -49,11 +84,6 @@ "version": "v7.4.4", "date": "2025-06-30T13:04:22Z" }, - { - "name": "keycloak/keycloak", - "version": "26.3.0", - "date": "2025-06-30T12:53:32Z" - }, { "name": "Graylog2/graylog2-server", "version": "6.3.0", @@ -84,11 +114,6 @@ "version": "preview-v0.1", "date": "2025-06-27T14:35:47Z" }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2097", - "date": "2025-06-30T05:53:30Z" - }, { "name": "typesense/typesense", "version": "v29.0", @@ -189,11 +214,6 @@ "version": "341.1", "date": "2025-06-27T08:50:16Z" }, - { - "name": "zabbix/zabbix", - "version": "7.2.10", - "date": "2025-06-27T06:40:00Z" - }, { "name": "MediaBrowser/Emby.Releases", "version": "4.9.1.2", @@ -304,11 +324,6 @@ "version": "v1.132.0", "date": "2025-06-17T13:49:30Z" }, - { - "name": "Checkmk/checkmk", - "version": "v2.4.0p5", - "date": "2025-06-24T13:06:53Z" - }, { "name": "fallenbagel/jellyseerr", "version": "preview-fix-proxy-axios", @@ -326,8 +341,8 @@ }, { "name": "runtipi/runtipi", - "version": "nightly", - "date": "2025-06-23T19:10:33Z" + "version": "v4.2.1", + "date": "2025-06-03T20:04:28Z" }, { "name": "VictoriaMetrics/VictoriaMetrics", @@ -394,11 +409,6 @@ "version": "v4.0.15.2941", "date": "2025-06-20T17:20:54Z" }, - { - "name": "syncthing/syncthing", - "version": "2.0.0-rc.19", - "date": "2025-06-02T17:56:25Z" - }, { "name": "benzino77/tasmocompiler", "version": "v12.7.0", @@ -458,40 +468,5 @@ "name": "Bubka/2FAuth", "version": "v5.6.0", "date": "2025-06-18T12:19:54Z" - }, - { - "name": "zwave-js/zwave-js-ui", - "version": "v10.7.0", - "date": "2025-06-18T11:57:05Z" - }, - { - "name": "forgejo/forgejo", - "version": "v11.0.2", - "date": "2025-06-18T09:38:19Z" - }, - { - "name": "silverbulletmd/silverbullet", - "version": "2.0.0-pre3", - "date": "2025-06-18T08:01:24Z" - }, - { - "name": "cross-seed/cross-seed", - "version": "v6.12.7", - "date": "2025-06-18T03:44:24Z" - }, - { - "name": "grafana/grafana", - "version": "v11.5.6", - "date": "2025-06-17T22:00:40Z" - }, - { - "name": "project-zot/zot", - "version": "v2.1.5", - "date": "2025-06-17T18:04:11Z" - }, - { - "name": "cloudflare/cloudflared", - "version": "2025.6.1", - "date": "2025-06-17T12:45:39Z" } ] From f4fac315129139bba323e22b0233826b24da403b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 14:45:17 +0200 Subject: [PATCH 103/463] Update itsmng-install.sh --- install/itsmng-install.sh | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/install/itsmng-install.sh b/install/itsmng-install.sh index 2879d1ca..84ccbbf5 100644 --- a/install/itsmng-install.sh +++ b/install/itsmng-install.sh @@ -15,21 +15,11 @@ update_os setup_mariadb -msg_info "Installing Repository" -curl -fsSL http://deb.itsm-ng.org/pubkey.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/itsm-ng-keyring.gpg -echo "deb http://deb.itsm-ng.org/$(. /etc/os-release && echo "$ID")/ $(. /etc/os-release && echo "$VERSION_CODENAME") main" > /etc/apt/sources.list.d/itsm-ng.list -$STD apt update -msg_ok "Installed Repository" - -msg_info "Installing ITSM-NG" -$STD apt install -y itsm-ng -msg_ok "Installed ITSM-NG" - msg_info "Setting up database" DB_NAME=itsmng_db DB_USER=itsmng DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) -mariadb-tzinfo-to-sql /usr/share/zoneinfo | mysql mysql +mariadb-tzinfo-to-sql /usr/share/zoneinfo | mariadb mysql mariadb -u root -e "CREATE DATABASE $DB_NAME;" mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" mariadb -u root -e "GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost';" @@ -42,20 +32,21 @@ mariadb -u root -e "GRANT SELECT ON \`mysql\`.\`time_zone_name\` TO '$DB_USER'@' } >>~/itsmng_db.creds msg_ok "Set up database" +msg_info "Setup ITSM-NG Repository" +curl -fsSL http://deb.itsm-ng.org/pubkey.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/itsm-ng-keyring.gpg +echo "deb http://deb.itsm-ng.org/$(. /etc/os-release && echo "$ID")/ $(. /etc/os-release && echo "$VERSION_CODENAME") main" >/etc/apt/sources.list.d/itsm-ng.list +$STD apt-get update +msg_ok "Setup ITSM-NG Repository" + msg_info "Installing ITSM-NG" +$STD apt install -y itsm-ng cd /usr/share/itsm-ng $STD php bin/console db:install --db-name=$DB_NAME --db-user=$DB_USER --db-password=$DB_PASS --no-interaction +$STD a2dissite 000-default.conf +echo "* * * * * php /usr/share/itsm-ng/front/cron.php" | crontab - msg_ok "Installed ITSM-NG" -msg_info "Configuring webserver" -$STD a2dissite 000-default.conf -msg_ok "Setup Service" - -msg_info "Setup Cronjob" -echo "* * * * * php /usr/share/itsm-ng/front/cron.php" | crontab - -msg_ok "Setup Cronjob" - -msg_info "Update PHP Params" +msg_info "Increase PHP Params" PHP_VERSION=$(ls /etc/php/ | grep -E '^[0-9]+\.[0-9]+$' | head -n 1) PHP_INI="/etc/php/$PHP_VERSION/apache2/php.ini" sed -i 's/^upload_max_filesize = .*/upload_max_filesize = 20M/' $PHP_INI From 3116c7a0ccf5526f0723659288af4eff7c17d040 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 14:46:03 +0200 Subject: [PATCH 104/463] Update itsmng.sh --- ct/itsmng.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/itsmng.sh b/ct/itsmng.sh index b0117b05..b7a2ff98 100644 --- a/ct/itsmng.sh +++ b/ct/itsmng.sh @@ -5,7 +5,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://itsm-ng.com/ -APP="itsmng" +APP="ITSM-NG" var_tags="${var_tags:-asset-management;foss}" var_cpu="${var_cpu:-2}" var_ram="${var_ram:-2048}" @@ -30,9 +30,9 @@ function update_script() { fi msg_info "Updating ${APP} LXC" - $STD apt-get update - $STD apt-get -y upgrade - msg_ok "Updated Successfully" + $STD apt-get update + $STD apt-get -y upgrade + msg_ok "Updated Successfully" exit } From 562c7448c60c6f1af3f8140c4d66aad7ec61b381 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 12:46:27 +0000 Subject: [PATCH 105/463] Update .app files (#661) Co-authored-by: GitHub Actions --- ct/headers/itsmng | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/headers/itsmng b/ct/headers/itsmng index bbb5bb64..3af6235e 100644 --- a/ct/headers/itsmng +++ b/ct/headers/itsmng @@ -1,6 +1,6 @@ - _ __ - (_) /__________ ___ ____ ____ _ - / / __/ ___/ __ `__ \/ __ \/ __ `/ - / / /_(__ ) / / / / / / / / /_/ / -/_/\__/____/_/ /_/ /_/_/ /_/\__, / - /____/ + _______________ __ ___ _ ________ + / _/_ __/ ___// |/ / / | / / ____/ + / / / / \__ \/ /|_/ /_____/ |/ / / __ + _/ / / / ___/ / / / /_____/ /| / /_/ / +/___/ /_/ /____/_/ /_/ /_/ |_/\____/ + From be7f3ed82b7e57e231d8cb46f4e3c5d3a5452ae1 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 14:50:29 +0200 Subject: [PATCH 106/463] fixes --- ct/{itsmng.sh => itsm-ng.sh} | 0 frontend/public/json/itsm-ng.json | 35 +++++++++++++++++++ frontend/public/json/itsmng.json | 35 ------------------- .../{itsmng-install.sh => itsm-ng-install.sh} | 0 4 files changed, 35 insertions(+), 35 deletions(-) rename ct/{itsmng.sh => itsm-ng.sh} (100%) create mode 100644 frontend/public/json/itsm-ng.json delete mode 100644 frontend/public/json/itsmng.json rename install/{itsmng-install.sh => itsm-ng-install.sh} (100%) diff --git a/ct/itsmng.sh b/ct/itsm-ng.sh similarity index 100% rename from ct/itsmng.sh rename to ct/itsm-ng.sh diff --git a/frontend/public/json/itsm-ng.json b/frontend/public/json/itsm-ng.json new file mode 100644 index 00000000..d24aa8d1 --- /dev/null +++ b/frontend/public/json/itsm-ng.json @@ -0,0 +1,35 @@ +{ + "name": "ITSM-NG", + "slug": "itsm-ng", + "categories": [ + 25 + ], + "date_created": "2025-06-20", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 80, + "documentation": "https://wiki.itsm-ng.org/en/home", + "website": "https://itsm-ng.com", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/itsm-ng.svg", + "config_path": "/etc/itsm-ng", + "description": "ITSM-NG is a powerful, open-source IT Service Management (ITSM) solution designed for managing IT assets, software, licenses, and support processes in accordance with ITIL best practices. It offers integrated features for asset inventory, incident tracking, problem management, change requests, and service desk workflows.", + "install_methods": [ + { + "type": "default", + "script": "ct/itsmng.sh", + "resources": { + "cpu": 2, + "ram": 2048, + "hdd": 10, + "os": "debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": "itsm", + "password": "itsm" + }, + "notes": [] +} diff --git a/frontend/public/json/itsmng.json b/frontend/public/json/itsmng.json deleted file mode 100644 index a3bef7af..00000000 --- a/frontend/public/json/itsmng.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "ITSMNG", - "slug": "itsmng", - "categories": [ - 25 - ], - "date_created": "2025-06-20", - "type": "ct", - "updateable": true, - "privileged": false, - "interface_port": 80, - "documentation": "https://wiki.itsm-ng.org/en/home", - "website": "https://itsm-ng.com", - "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/itsm-ng.svg", - "config_path": "/etc/itsm-ng", - "description": "ITSM-NG is a Free Asset and IT Management Software package, Data center management, ITIL Service Desk, licenses tracking and software auditing.", - "install_methods": [ - { - "type": "default", - "script": "ct/itsmng.sh", - "resources": { - "cpu": 2, - "ram": 2048, - "hdd": 10, - "os": "debian", - "version": "12" - } - } - ], - "default_credentials": { - "username": "itsm", - "password": "itsm" - }, - "notes": [] -} diff --git a/install/itsmng-install.sh b/install/itsm-ng-install.sh similarity index 100% rename from install/itsmng-install.sh rename to install/itsm-ng-install.sh From e4052700eee6fdee620b29c7780d0974ac19a28f Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 12:50:55 +0000 Subject: [PATCH 107/463] Update .app files (#662) Co-authored-by: GitHub Actions --- ct/headers/{itsmng => itsm-ng} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/headers/{itsmng => itsm-ng} (100%) diff --git a/ct/headers/itsmng b/ct/headers/itsm-ng similarity index 100% rename from ct/headers/itsmng rename to ct/headers/itsm-ng From 44d74815e6f174de88147380f20e5f4afa7fe392 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 14:53:38 +0200 Subject: [PATCH 108/463] Update itsm-ng.json --- frontend/public/json/itsm-ng.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/public/json/itsm-ng.json b/frontend/public/json/itsm-ng.json index d24aa8d1..c9b561c8 100644 --- a/frontend/public/json/itsm-ng.json +++ b/frontend/public/json/itsm-ng.json @@ -17,7 +17,7 @@ "install_methods": [ { "type": "default", - "script": "ct/itsmng.sh", + "script": "ct/itsm-ng.sh", "resources": { "cpu": 2, "ram": 2048, From 7a1d0720533cdd24b25b36e001a986ca2788213b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 14:57:59 +0200 Subject: [PATCH 109/463] Update create_lxc.sh --- misc/create_lxc.sh | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index a1918743..255a35ea 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -56,24 +56,19 @@ function check_storage_support() { local CURRENT_NAME="" CURRENT_CONTENTS=() while IFS= read -r line || [[ -n "$line" ]]; do - # Prüfen auf Storage-Typ-Zeile (dir:, lvm:, lvmthin:, zfspool:) - if [[ "$line" =~ ^(dir|lvm|lvmthin|zfspool):[[:space:]]*([a-zA-Z0-9._-]+) ]]; then + # Neue Storage-Definition erkannt + if [[ "$line" =~ ^[[:space:]]*(dir|lvm|lvmthin|zfspool):[[:space:]]*([a-zA-Z0-9._-]+) ]]; then if [[ -n "$CURRENT_NAME" && "${#CURRENT_CONTENTS[@]}" -gt 0 ]]; then if [[ " ${CURRENT_CONTENTS[*]} " =~ " $CONTENT " ]]; then VALID_STORAGES+=("$CURRENT_NAME") fi fi - - # Nur wenn der Regex gematcht hat, darf man auf BASH_REMATCH zugreifen - CURRENT_NAME="" - if [[ ${#BASH_REMATCH[@]} -ge 3 ]]; then - CURRENT_NAME="${BASH_REMATCH[2]}" - CURRENT_CONTENTS=() - fi + CURRENT_NAME="${BASH_REMATCH[2]}" + CURRENT_CONTENTS=() continue fi - # Content-Zeile + # Content-Zeile erkannt if [[ "$line" =~ ^[[:space:]]*content[[:space:]]*=?[[:space:]]*(.+)$ ]]; then IFS=',' read -ra PARTS <<<"${BASH_REMATCH[1]}" for c in "${PARTS[@]}"; do From c1cb56ba495be4732a850c98db36a582c0db0f24 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 15:00:41 +0200 Subject: [PATCH 110/463] Update create_lxc.sh --- misc/create_lxc.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 255a35ea..4ae2b0f8 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -56,8 +56,9 @@ function check_storage_support() { local CURRENT_NAME="" CURRENT_CONTENTS=() while IFS= read -r line || [[ -n "$line" ]]; do - # Neue Storage-Definition erkannt + # Prüfen auf neue Storage-Definition (nur bei erfolgreichem Match BASH_REMATCH verwenden!) if [[ "$line" =~ ^[[:space:]]*(dir|lvm|lvmthin|zfspool):[[:space:]]*([a-zA-Z0-9._-]+) ]]; then + # vorherigen Block prüfen if [[ -n "$CURRENT_NAME" && "${#CURRENT_CONTENTS[@]}" -gt 0 ]]; then if [[ " ${CURRENT_CONTENTS[*]} " =~ " $CONTENT " ]]; then VALID_STORAGES+=("$CURRENT_NAME") @@ -65,11 +66,7 @@ function check_storage_support() { fi CURRENT_NAME="${BASH_REMATCH[2]}" CURRENT_CONTENTS=() - continue - fi - - # Content-Zeile erkannt - if [[ "$line" =~ ^[[:space:]]*content[[:space:]]*=?[[:space:]]*(.+)$ ]]; then + elif [[ "$line" =~ ^[[:space:]]*content[[:space:]]*=?[[:space:]]*(.+)$ ]]; then IFS=',' read -ra PARTS <<<"${BASH_REMATCH[1]}" for c in "${PARTS[@]}"; do CURRENT_CONTENTS+=("$(echo "$c" | xargs)") From 3ce47157bdc793561f9ac5608e9288d7ba1d28e0 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 15:02:46 +0200 Subject: [PATCH 111/463] Update create_lxc.sh --- misc/create_lxc.sh | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 4ae2b0f8..7df5022d 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -53,33 +53,12 @@ function on_terminate() { function check_storage_support() { local CONTENT="$1" local -a VALID_STORAGES=() - local CURRENT_NAME="" CURRENT_CONTENTS=() - while IFS= read -r line || [[ -n "$line" ]]; do - # Prüfen auf neue Storage-Definition (nur bei erfolgreichem Match BASH_REMATCH verwenden!) - if [[ "$line" =~ ^[[:space:]]*(dir|lvm|lvmthin|zfspool):[[:space:]]*([a-zA-Z0-9._-]+) ]]; then - # vorherigen Block prüfen - if [[ -n "$CURRENT_NAME" && "${#CURRENT_CONTENTS[@]}" -gt 0 ]]; then - if [[ " ${CURRENT_CONTENTS[*]} " =~ " $CONTENT " ]]; then - VALID_STORAGES+=("$CURRENT_NAME") - fi - fi - CURRENT_NAME="${BASH_REMATCH[2]}" - CURRENT_CONTENTS=() - elif [[ "$line" =~ ^[[:space:]]*content[[:space:]]*=?[[:space:]]*(.+)$ ]]; then - IFS=',' read -ra PARTS <<<"${BASH_REMATCH[1]}" - for c in "${PARTS[@]}"; do - CURRENT_CONTENTS+=("$(echo "$c" | xargs)") - done - fi - done /dev/null | awk 'NR>1') [[ ${#VALID_STORAGES[@]} -gt 0 ]] } From c447439580aa29bfad6af69b30ba803d5d34d7b9 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 15:05:55 +0200 Subject: [PATCH 112/463] Update create_lxc.sh --- misc/create_lxc.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 7df5022d..13e23ff4 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -148,7 +148,8 @@ function select_storage() { DISPLAY_SELECTED=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ 16 "$WIDTH" 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { - msg_error "Storage selection cancelled by user." + printf "\e[?25h" + msg_error "Storage selection cancelled by user. Aborting script." exit 202 } From c7a0b671cbbe1206f5baba0f928ed382d817f2fb Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 15:08:43 +0200 Subject: [PATCH 113/463] Update create_lxc.sh --- misc/create_lxc.sh | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 13e23ff4..c12e9cd6 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -194,10 +194,28 @@ if [[ -f "$DEFAULT_FILE" ]]; then msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage." fi else - TEMPLATE_STORAGE=$(select_storage template) + # TEMPLATE STORAGE SELECTION + if ! TEMPLATE_STORAGE=$(select_storage template); then + [[ $? -eq 202 ]] && { + msg_error "Template Storage selection cancelled by user. Exiting cleanly." + exit 202 + } + msg_error "Unexpected error during template storage selection." + exit 1 + fi msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage." - CONTAINER_STORAGE=$(select_storage container) + + # CONTAINER STORAGE SELECTION + if ! CONTAINER_STORAGE=$(select_storage container); then + [[ $? -eq 202 ]] && { + msg_error "Container Storage selection cancelled by user. Exiting cleanly." + exit 202 + } + msg_error "Unexpected error during container storage selection." + exit 1 + fi msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage." + fi # Check free space on selected container storage From 633a22361e149da60711d610457ee9bcb90cc8b3 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 15:09:49 +0200 Subject: [PATCH 114/463] Update tools.func --- misc/tools.func | 3 --- 1 file changed, 3 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 089cef29..f9d4e36d 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -238,7 +238,6 @@ setup_mariadb() { msg_info "Setting up MariaDB $MARIADB_VERSION" # grab dynamic latest LTS version if [[ "$MARIADB_VERSION" == "latest" ]]; then - $STD msg_info "Resolving latest GA MariaDB version" MARIADB_VERSION=$(curl -fsSL http://mirror.mariadb.org/repo/ | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+/' | grep -vE 'rc/|rolling/' | @@ -249,7 +248,6 @@ setup_mariadb() { msg_error "Could not determine latest GA MariaDB version" return 1 fi - $STD msg_ok "Latest GA MariaDB version is $MARIADB_VERSION" fi local CURRENT_VERSION="" @@ -274,7 +272,6 @@ setup_mariadb() { $STD msg_info "Setup MariaDB $MARIADB_VERSION" fi - $STD msg_info "Setting up MariaDB Repository" curl -fsSL "https://mariadb.org/mariadb_release_signing_key.asc" | gpg --dearmor -o /etc/apt/trusted.gpg.d/mariadb.gpg From e272e5d01efb0a4334c23bca9018aa3b604e5c2d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 15:12:02 +0200 Subject: [PATCH 115/463] Update create_lxc.sh --- misc/create_lxc.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index c12e9cd6..8ecbe03f 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -195,21 +195,22 @@ if [[ -f "$DEFAULT_FILE" ]]; then fi else # TEMPLATE STORAGE SELECTION + # Template Storage if ! TEMPLATE_STORAGE=$(select_storage template); then [[ $? -eq 202 ]] && { - msg_error "Template Storage selection cancelled by user. Exiting cleanly." - exit 202 + msg_error "Template Storage selection cancelled by user. Exiting." + kill -INT $$ } msg_error "Unexpected error during template storage selection." exit 1 fi msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage." - # CONTAINER STORAGE SELECTION + # Container Storage if ! CONTAINER_STORAGE=$(select_storage container); then [[ $? -eq 202 ]] && { - msg_error "Container Storage selection cancelled by user. Exiting cleanly." - exit 202 + msg_error "Container Storage selection cancelled by user. Exiting." + kill -INT $$ } msg_error "Unexpected error during container storage selection." exit 1 From 362b3b5679cc3475a928fd035c05f0337431d536 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 15:25:06 +0200 Subject: [PATCH 116/463] Update build.func --- misc/build.func | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/misc/build.func b/misc/build.func index 8d03ff53..74d9c166 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1195,12 +1195,10 @@ build_container() { -unprivileged $CT_TYPE $PW " - # This executes create_lxc.sh and creates the container and .conf file - CREATE_CMD="bash -c \"\$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)\"" - eval "$CREATE_CMD" + bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)" RET=$? if [[ $RET -ne 0 ]]; then - msg_error "in line $LINENO: exit code $RET: while executing command $CREATE_CMD" + msg_error "in line $LINENO: exit code $RET: while executing create_lxc.sh" exit $RET fi From 0a1d2637ffa6d777f4c13c842e6d1ccd5023eb3f Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 15:27:32 +0200 Subject: [PATCH 117/463] Update build.func --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 74d9c166..bc384860 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1198,7 +1198,7 @@ build_container() { bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)" RET=$? if [[ $RET -ne 0 ]]; then - msg_error "in line $LINENO: exit code $RET: while executing create_lxc.sh" + msg_error "rny: in line $LINENO: exit code $RET: while executing create_lxc.sh" exit $RET fi From 82dcad5cae2faf7b2818f1fe741ee0da33a82af8 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 15:34:54 +0200 Subject: [PATCH 118/463] Update create_lxc.sh --- misc/create_lxc.sh | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 8ecbe03f..87b3c0c0 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -144,16 +144,25 @@ function select_storage() { fi local WIDTH=$((COL_WIDTH + 42)) - local DISPLAY_SELECTED - DISPLAY_SELECTED=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ - 16 "$WIDTH" 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { - printf "\e[?25h" - msg_error "Storage selection cancelled by user. Aborting script." - exit 202 - } + local DISPLAY_SELECTED="" + while true; do + DISPLAY_SELECTED=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ + "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ + 16 "$WIDTH" 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { + msg_error "Storage selection cancelled by user." + exit 202 + } + + if [[ -z "$DISPLAY_SELECTED" ]]; then + whiptail --backtitle "Proxmox VE Helper Scripts" --title "Invalid Selection" \ + --msgbox "No storage selected. Please choose a storage pool to continue." 9 60 + else + break + fi + done echo "${STORAGE_MAP["$DISPLAY_SELECTED"]}" + } # Test if required variables are set From 689f2cc999223ca9e85b1d26315fab73e266241e Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 1 Jul 2025 15:54:23 +0200 Subject: [PATCH 119/463] Update create_lxc.sh --- misc/create_lxc.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 87b3c0c0..98b4d68e 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -153,12 +153,14 @@ function select_storage() { exit 202 } - if [[ -z "$DISPLAY_SELECTED" ]]; then + # Validierung gegen STORAGE_MAP + if [[ -z "$DISPLAY_SELECTED" || -z "${STORAGE_MAP[$DISPLAY_SELECTED]+_}" ]]; then whiptail --backtitle "Proxmox VE Helper Scripts" --title "Invalid Selection" \ - --msgbox "No storage selected. Please choose a storage pool to continue." 9 60 - else - break + --msgbox "No valid storage selected. Please choose a storage pool to continue." 9 60 + continue fi + + break done echo "${STORAGE_MAP["$DISPLAY_SELECTED"]}" From e9746cb99edbcd1241004df1a7f436761535a52e Mon Sep 17 00:00:00 2001 From: tremor021 Date: Tue, 1 Jul 2025 16:02:14 +0200 Subject: [PATCH 120/463] Update ITSM --- install/itsm-ng-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/itsm-ng-install.sh b/install/itsm-ng-install.sh index 84ccbbf5..769ee0b7 100644 --- a/install/itsm-ng-install.sh +++ b/install/itsm-ng-install.sh @@ -52,7 +52,7 @@ PHP_INI="/etc/php/$PHP_VERSION/apache2/php.ini" sed -i 's/^upload_max_filesize = .*/upload_max_filesize = 20M/' $PHP_INI sed -i 's/^post_max_size = .*/post_max_size = 20M/' $PHP_INI sed -i 's/^max_execution_time = .*/max_execution_time = 60/' $PHP_INI -sed -i 's/^max_input_vars = .*/max_input_vars = 5000/' $PHP_INI +sed -i 's/^[;]*max_input_vars *=.*/max_input_vars = 5000/' "$PHP_INI" sed -i 's/^memory_limit = .*/memory_limit = 256M/' $PHP_INI sed -i 's/^;\?\s*session.cookie_httponly\s*=.*/session.cookie_httponly = On/' $PHP_INI systemctl restart apache2 From 3143005128208dd76c49e71a2d23267df6199c20 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 1 Jul 2025 20:02:26 +0000 Subject: [PATCH 121/463] Deleted files for issue: ITSM-NG --- ct/itsm-ng.sh | 47 --------------------- frontend/public/json/itsm-ng.json | 35 ---------------- install/itsm-ng-install.sh | 68 ------------------------------- 3 files changed, 150 deletions(-) delete mode 100644 ct/itsm-ng.sh delete mode 100644 frontend/public/json/itsm-ng.json delete mode 100644 install/itsm-ng-install.sh diff --git a/ct/itsm-ng.sh b/ct/itsm-ng.sh deleted file mode 100644 index b7a2ff98..00000000 --- a/ct/itsm-ng.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2025 community-scripts ORG -# Author: Florianb63 -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://itsm-ng.com/ - -APP="ITSM-NG" -var_tags="${var_tags:-asset-management;foss}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-2048}" -var_disk="${var_disk:-10}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -var_unprivileged="${var_unprivileged:-1}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - header_info - check_container_storage - check_container_resources - - if [[ ! -f /etc/itsm-ng/config_db.php ]]; then - msg_error "No ${APP} Installation Found!" - exit 1 - fi - - msg_info "Updating ${APP} LXC" - $STD apt-get update - $STD apt-get -y upgrade - 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}${CL}" diff --git a/frontend/public/json/itsm-ng.json b/frontend/public/json/itsm-ng.json deleted file mode 100644 index c9b561c8..00000000 --- a/frontend/public/json/itsm-ng.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "ITSM-NG", - "slug": "itsm-ng", - "categories": [ - 25 - ], - "date_created": "2025-06-20", - "type": "ct", - "updateable": true, - "privileged": false, - "interface_port": 80, - "documentation": "https://wiki.itsm-ng.org/en/home", - "website": "https://itsm-ng.com", - "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/itsm-ng.svg", - "config_path": "/etc/itsm-ng", - "description": "ITSM-NG is a powerful, open-source IT Service Management (ITSM) solution designed for managing IT assets, software, licenses, and support processes in accordance with ITIL best practices. It offers integrated features for asset inventory, incident tracking, problem management, change requests, and service desk workflows.", - "install_methods": [ - { - "type": "default", - "script": "ct/itsm-ng.sh", - "resources": { - "cpu": 2, - "ram": 2048, - "hdd": 10, - "os": "debian", - "version": "12" - } - } - ], - "default_credentials": { - "username": "itsm", - "password": "itsm" - }, - "notes": [] -} diff --git a/install/itsm-ng-install.sh b/install/itsm-ng-install.sh deleted file mode 100644 index 769ee0b7..00000000 --- a/install/itsm-ng-install.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 community-scripts ORG -# Author: Florianb63 -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://itsm-ng.com/ - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -setup_mariadb - -msg_info "Setting up database" -DB_NAME=itsmng_db -DB_USER=itsmng -DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) -mariadb-tzinfo-to-sql /usr/share/zoneinfo | mariadb mysql -mariadb -u root -e "CREATE DATABASE $DB_NAME;" -mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" -mariadb -u root -e "GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost';" -mariadb -u root -e "GRANT SELECT ON \`mysql\`.\`time_zone_name\` TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" -{ - echo "ITSM-NG Database Credentials" - echo "Database: $DB_NAME" - echo "Username: $DB_USER" - echo "Password: $DB_PASS" -} >>~/itsmng_db.creds -msg_ok "Set up database" - -msg_info "Setup ITSM-NG Repository" -curl -fsSL http://deb.itsm-ng.org/pubkey.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/itsm-ng-keyring.gpg -echo "deb http://deb.itsm-ng.org/$(. /etc/os-release && echo "$ID")/ $(. /etc/os-release && echo "$VERSION_CODENAME") main" >/etc/apt/sources.list.d/itsm-ng.list -$STD apt-get update -msg_ok "Setup ITSM-NG Repository" - -msg_info "Installing ITSM-NG" -$STD apt install -y itsm-ng -cd /usr/share/itsm-ng -$STD php bin/console db:install --db-name=$DB_NAME --db-user=$DB_USER --db-password=$DB_PASS --no-interaction -$STD a2dissite 000-default.conf -echo "* * * * * php /usr/share/itsm-ng/front/cron.php" | crontab - -msg_ok "Installed ITSM-NG" - -msg_info "Increase PHP Params" -PHP_VERSION=$(ls /etc/php/ | grep -E '^[0-9]+\.[0-9]+$' | head -n 1) -PHP_INI="/etc/php/$PHP_VERSION/apache2/php.ini" -sed -i 's/^upload_max_filesize = .*/upload_max_filesize = 20M/' $PHP_INI -sed -i 's/^post_max_size = .*/post_max_size = 20M/' $PHP_INI -sed -i 's/^max_execution_time = .*/max_execution_time = 60/' $PHP_INI -sed -i 's/^[;]*max_input_vars *=.*/max_input_vars = 5000/' "$PHP_INI" -sed -i 's/^memory_limit = .*/memory_limit = 256M/' $PHP_INI -sed -i 's/^;\?\s*session.cookie_httponly\s*=.*/session.cookie_httponly = On/' $PHP_INI -systemctl restart apache2 -msg_ok "Update PHP Params" - -motd_ssh -customize - -msg_info "Cleaning up" -rm -rf /usr/share/itsm-ng/install -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" From 2b21c90ed239d481fb12623210f838847b61d745 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 20:07:34 +0000 Subject: [PATCH 122/463] Update .app files (#664) Co-authored-by: GitHub Actions --- ct/headers/itsm-ng | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 ct/headers/itsm-ng diff --git a/ct/headers/itsm-ng b/ct/headers/itsm-ng deleted file mode 100644 index 3af6235e..00000000 --- a/ct/headers/itsm-ng +++ /dev/null @@ -1,6 +0,0 @@ - _______________ __ ___ _ ________ - / _/_ __/ ___// |/ / / | / / ____/ - / / / / \__ \/ /|_/ /_____/ |/ / / __ - _/ / / / ___/ / / / /_____/ /| / /_/ / -/___/ /_/ /____/_/ /_/ /_/ |_/\____/ - From f8186b5313561ffc62b2f415ad5132cbbefd9cf5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 1 Jul 2025 21:35:40 +0000 Subject: [PATCH 123/463] Deleted files for issue: Librespeed-Rust --- ct/librespeed-rust.sh | 54 ----------------------- frontend/public/json/librespeed-rust.json | 35 --------------- install/librespeed-rust-install.sh | 28 ------------ 3 files changed, 117 deletions(-) delete mode 100644 ct/librespeed-rust.sh delete mode 100644 frontend/public/json/librespeed-rust.json delete mode 100644 install/librespeed-rust-install.sh diff --git a/ct/librespeed-rust.sh b/ct/librespeed-rust.sh deleted file mode 100644 index 74847372..00000000 --- a/ct/librespeed-rust.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2025 community-scripts ORG -# Author: Joseph Stubberfield (stubbers) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/librespeed/speedtest-rust - -APP="Librespeed-Rust" -var_tags="${var_tags:-network}" -var_cpu="${var_cpu:-1}" -var_ram="${var_ram:-512}" -var_disk="${var_disk:-4}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -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 /var/lib/librespeed-rs ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - RELEASE=$(curl -fsSL https://api.github.com/repos/librespeed/speedtest-rust/releases/latest | grep '"tag_name"' | sed -E 's/.*"tag_name": "v([^"]+).*/\1/') - if [[ "${RELEASE}" != "$(cat ~/.librespeed 2>/dev/null)" ]] || [[ ! -f ~/.librespeed ]]; then - msg_info "Stopping Services" - systemctl stop librespeed-rs - msg_ok "Services Stopped" - - fetch_and_deploy_gh_release "librespeed-rust" "librespeed/speedtest-rust" "binary" "latest" "/opt/librespeed-rust" "librespeed-rs-x86_64-unknown-linux-gnu.deb" - - msg_info "Starting Service" - systemctl start librespeed-rs - msg_ok "Started Service" - else - msg_ok "No update required. ${APP} is already at v${RELEASE}" - 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}http://${IP}:8080${CL}" diff --git a/frontend/public/json/librespeed-rust.json b/frontend/public/json/librespeed-rust.json deleted file mode 100644 index 753b408a..00000000 --- a/frontend/public/json/librespeed-rust.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "Librespeed Rust", - "slug": "librespeed-rust", - "categories": [ - 4 - ], - "date_created": "2025-06-27", - "type": "ct", - "updateable": true, - "privileged": false, - "config_path": "/var/lib/librespeed-rs/configs.toml", - "interface_port": 8080, - "documentation": "https://github.com/librespeed/speedtest-rust", - "website": "https://github.com/librespeed/speedtest-rust", - "logo": "https://raw.githubusercontent.com/selfhst/icons/refs/heads/main/svg/librespeed.svg", - "description": "Librespeed is a no flash, no java, no websocket speedtest server. This community script deploys the rust version for simplicity and low resource usage.", - "install_methods": [ - { - "type": "default", - "script": "ct/librespeed-rust.sh", - "resources": { - "cpu": 1, - "ram": 512, - "hdd": 4, - "os": "Debian", - "version": "12" - } - } - ], - "default_credentials": { - "username": null, - "password": null - }, - "notes": [] -} diff --git a/install/librespeed-rust-install.sh b/install/librespeed-rust-install.sh deleted file mode 100644 index 7013543f..00000000 --- a/install/librespeed-rust-install.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 community-scripts ORG -# Author: Joseph Stubberfield (stubbers) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/librespeed/speedtest-rust - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -fetch_and_deploy_gh_release "librespeed-rust" "librespeed/speedtest-rust" "binary" "latest" "/opt/librespeed-rust" "librespeed-rs-x86_64-unknown-linux-gnu.deb" - -msg_info "Enabling Service" -systemctl enable -q --now speedtest_rs.service -msg_ok "Enabled Service" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" From c0a47eb2b7e92a3d62ed1bac3eadfa23180cdab0 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Wed, 2 Jul 2025 01:39:40 +0000 Subject: [PATCH 124/463] Update versions.json (#667) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 172 ++++++++++++++--------------- 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 35a70510..d0529c98 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,84 @@ [ + { + "name": "diced/zipline", + "version": "v4.2.0", + "date": "2025-07-02T00:45:31Z" + }, + { + "name": "sysadminsmedia/homebox", + "version": "v0.20.2", + "date": "2025-07-02T00:37:07Z" + }, + { + "name": "hyperion-project/hyperion.ng", + "version": "2.1.1", + "date": "2025-06-14T17:45:06Z" + }, + { + "name": "mongodb/mongo", + "version": "r8.1.2", + "date": "2025-07-01T22:39:32Z" + }, + { + "name": "Threadfin/Threadfin", + "version": "1.2.35", + "date": "2025-07-01T21:37:20Z" + }, + { + "name": "apache/tomcat", + "version": "10.1.43", + "date": "2025-07-01T21:32:34Z" + }, + { + "name": "actualbudget/actual", + "version": "v25.7.0", + "date": "2025-07-01T21:02:27Z" + }, + { + "name": "home-assistant/core", + "version": "2025.6.3", + "date": "2025-06-24T13:00:12Z" + }, + { + "name": "TwiN/gatus", + "version": "v5.19.0", + "date": "2025-07-01T19:59:32Z" + }, + { + "name": "Koenkk/zigbee2mqtt", + "version": "2.5.0", + "date": "2025-07-01T18:28:01Z" + }, + { + "name": "hivemq/hivemq-community-edition", + "version": "2025.4", + "date": "2025-07-01T18:01:37Z" + }, + { + "name": "HabitRPG/habitica", + "version": "v5.37.1", + "date": "2025-07-01T16:57:43Z" + }, + { + "name": "navidrome/navidrome", + "version": "v0.57.0", + "date": "2025-07-01T16:47:46Z" + }, + { + "name": "jenkinsci/jenkins", + "version": "jenkins-2.517", + "date": "2025-07-01T16:08:23Z" + }, + { + "name": "element-hq/synapse", + "version": "v1.133.0", + "date": "2025-07-01T15:13:42Z" + }, + { + "name": "keycloak/keycloak", + "version": "26.3.0", + "date": "2025-07-01T13:18:12Z" + }, { "name": "syncthing/syncthing", "version": "v1.30.0", @@ -9,11 +89,6 @@ "version": "v2.2.0p44-rc1", "date": "2025-07-01T11:10:25Z" }, - { - "name": "keycloak/keycloak", - "version": "26.3.0", - "date": "2025-07-01T10:32:30Z" - }, { "name": "rcourtman/Pulse", "version": "v99.99.99", @@ -34,6 +109,11 @@ "version": "v0.15.0-rc3", "date": "2025-07-01T04:09:37Z" }, + { + "name": "wazuh/wazuh", + "version": "coverity-w27-4.13.0", + "date": "2025-07-01T03:17:32Z" + }, { "name": "NginxProxyManager/nginx-proxy-manager", "version": "v2.12.4", @@ -44,21 +124,11 @@ "version": "v2.32.0", "date": "2025-06-30T22:12:48Z" }, - { - "name": "mongodb/mongo", - "version": "r8.0.11", - "date": "2025-06-30T20:30:31Z" - }, { "name": "docker/compose", "version": "v2.38.1", "date": "2025-06-30T20:07:35Z" }, - { - "name": "home-assistant/core", - "version": "2025.6.3", - "date": "2025-06-24T13:00:12Z" - }, { "name": "jhuckaby/Cronicle", "version": "v0.9.81", @@ -66,7 +136,7 @@ }, { "name": "ollama/ollama", - "version": "v0.9.4-rc5", + "version": "v0.9.4-rc6", "date": "2025-06-30T15:59:03Z" }, { @@ -124,11 +194,6 @@ "version": "v6.2.19", "date": "2025-06-28T06:53:45Z" }, - { - "name": "sysadminsmedia/homebox", - "version": "v0.20.0", - "date": "2025-06-29T18:50:03Z" - }, { "name": "dgtlmoon/changedetection.io", "version": "0.50.5", @@ -284,11 +349,6 @@ "version": "2.0.5", "date": "2025-06-25T14:53:31Z" }, - { - "name": "jenkinsci/jenkins", - "version": "jenkins-2.504.3", - "date": "2025-06-25T14:43:01Z" - }, { "name": "bunkerity/bunkerweb", "version": "testing", @@ -319,21 +379,11 @@ "version": "v2.18.0", "date": "2025-06-24T08:29:55Z" }, - { - "name": "element-hq/synapse", - "version": "v1.132.0", - "date": "2025-06-17T13:49:30Z" - }, { "name": "fallenbagel/jellyseerr", "version": "preview-fix-proxy-axios", "date": "2025-06-24T08:50:22Z" }, - { - "name": "wazuh/wazuh", - "version": "coverity-w26-4.13.0", - "date": "2025-06-24T02:02:34Z" - }, { "name": "minio/minio", "version": "RELEASE.2025-06-13T11-33-47Z", @@ -379,11 +429,6 @@ "version": "0.17.14", "date": "2025-06-21T23:43:04Z" }, - { - "name": "HabitRPG/habitica", - "version": "v5.37.0", - "date": "2025-06-21T14:05:12Z" - }, { "name": "rogerfar/rdt-client", "version": "v2.0.114", @@ -423,50 +468,5 @@ "name": "icereed/paperless-gpt", "version": "v0.21.0", "date": "2025-06-19T11:54:59Z" - }, - { - "name": "neo4j/neo4j", - "version": "2025.05.1", - "date": "2025-06-19T11:28:36Z" - }, - { - "name": "redis/redis", - "version": "8.2-m01-int2", - "date": "2025-06-12T08:52:10Z" - }, - { - "name": "prometheus-pve/prometheus-pve-exporter", - "version": "v3.5.5", - "date": "2025-06-19T05:43:47Z" - }, - { - "name": "docmost/docmost", - "version": "v0.21.0", - "date": "2025-06-18T21:43:27Z" - }, - { - "name": "ipfs/kubo", - "version": "v0.35.0", - "date": "2025-05-21T18:00:32Z" - }, - { - "name": "pterodactyl/panel", - "version": "v1.11.11", - "date": "2025-06-18T18:04:50Z" - }, - { - "name": "NodeBB/NodeBB", - "version": "v3.12.7", - "date": "2025-06-18T14:22:53Z" - }, - { - "name": "openhab/openhab-core", - "version": "5.0.0.M3", - "date": "2025-06-18T14:18:12Z" - }, - { - "name": "Bubka/2FAuth", - "version": "v5.6.0", - "date": "2025-06-18T12:19:54Z" } ] From 12ea2c5f36b6d0a816e462d6380bfbcce50959e3 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 2 Jul 2025 09:27:04 +0200 Subject: [PATCH 125/463] zigbee2mqtt testing node24 migration --- ct/zigbee2mqtt.sh | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 ct/zigbee2mqtt.sh diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh new file mode 100644 index 00000000..055497d4 --- /dev/null +++ b/ct/zigbee2mqtt.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://www.zigbee2mqtt.io/ + +APP="Zigbee2MQTT" +var_tags="${var_tags:-smarthome;zigbee;mqtt}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-1024}" +var_disk="${var_disk:-4}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +var_unprivileged="${var_unprivileged:-0}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + if [[ ! -d /opt/zigbee2mqtt ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + RELEASE=$(curl -fsSL https://api.github.com/repos/Koenkk/zigbee2mqtt/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + NODE_VERSION=24 + NODE_MODULE="pnpm@$(curl -fsSL https://raw.githubusercontent.com/Koenkk/zigbee2mqtt/master/package.json | jq -r '.packageManager | split("@")[1]')" + setup_nodejs + + msg_info "Stopping Service" + systemctl stop zigbee2mqtt + msg_ok "Stopped Service" + + msg_info "Creating Backup" + rm -rf /opt/${APP}_backup*.tar.gz + mkdir -p /opt/z2m_backup + $STD tar -czf /opt/z2m_backup/${APP}_backup_$(date +%Y%m%d%H%M%S).tar.gz -C /opt zigbee2mqtt + mv /opt/zigbee2mqtt/data /opt/z2m_backup + msg_ok "Backup Created" + + fetch_and_deploy_gh_release "Zigbee2MQTT" "Koenkk/zigbee2mqtt" "tarball" "latest" "/opt/zigbee2mqtt" + + msg_info "Updating ${APP} to v${RELEASE}" + rm -rf /opt/zigbee2mqtt/data + mv /opt/z2m_backup/data /opt/zigbee2mqtt + cd /opt/zigbee2mqtt + $STD pnpm install --frozen-lockfile + $STD pnpm build + msg_ok "Updated Zigbee2MQTT" + + msg_info "Starting Service" + systemctl start zigbee2mqtt + msg_ok "Started Service" + + msg_info "Cleaning up" + rm -rf /opt/z2m_backup + msg_ok "Cleaned up" + else + msg_ok "No update required. ${APP} is already at v${RELEASE}." + 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}http://${IP}:9442${CL}" From 7ed5202226b26da93771b15f09eb667f2aef7128 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 2 Jul 2025 09:36:44 +0200 Subject: [PATCH 126/463] Update zigbee2mqtt.sh --- ct/zigbee2mqtt.sh | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 055497d4..29c52eec 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -27,12 +27,19 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi - RELEASE=$(curl -fsSL https://api.github.com/repos/Koenkk/zigbee2mqtt/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then - NODE_VERSION=24 - NODE_MODULE="pnpm@$(curl -fsSL https://raw.githubusercontent.com/Koenkk/zigbee2mqtt/master/package.json | jq -r '.packageManager | split("@")[1]')" - setup_nodejs + if [[ -f ~/.zigbee2mqtt ]]; then + CURRENT="$(cat ~/.zigbee2mqtt)" + elif [[ -f /opt/${APP}_version.txt ]]; then + CURRENT="$(cat /opt/${APP}_version.txt)" + rm -f /opt/${APP}_version.txt + else + CURRENT="" + fi + + RELEASE=$(curl -fsSL https://api.github.com/repos/Koenkk/zigbee2mqtt/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + if [[ "$RELEASE" != "$CURRENT" ]]; then + NODE_VERSION=24 NODE_MODULE="pnpm@$(curl -fsSL https://raw.githubusercontent.com/Koenkk/zigbee2mqtt/master/package.json | jq -r '.packageManager | split("@")[1]')" setup_nodejs msg_info "Stopping Service" systemctl stop zigbee2mqtt @@ -62,6 +69,7 @@ function update_script() { msg_info "Cleaning up" rm -rf /opt/z2m_backup msg_ok "Cleaned up" + echo "${RELEASE}" >/opt/${APP}_version.txt else msg_ok "No update required. ${APP} is already at v${RELEASE}." fi From c566d6b5ede90dfda1776c1a602ef4be1414a222 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Wed, 2 Jul 2025 07:37:12 +0000 Subject: [PATCH 127/463] Update .app files (#669) Co-authored-by: GitHub Actions --- ct/headers/librespeed-rust | 6 ------ ct/headers/zigbee2mqtt | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 ct/headers/librespeed-rust create mode 100644 ct/headers/zigbee2mqtt diff --git a/ct/headers/librespeed-rust b/ct/headers/librespeed-rust deleted file mode 100644 index d032782a..00000000 --- a/ct/headers/librespeed-rust +++ /dev/null @@ -1,6 +0,0 @@ - __ _ __ __ ____ __ - / / (_) /_ ________ _________ ___ ___ ____/ / / __ \__ _______/ /_ - / / / / __ \/ ___/ _ \/ ___/ __ \/ _ \/ _ \/ __ /_____/ /_/ / / / / ___/ __/ - / /___/ / /_/ / / / __(__ ) /_/ / __/ __/ /_/ /_____/ _, _/ /_/ (__ ) /_ -/_____/_/_.___/_/ \___/____/ .___/\___/\___/\__,_/ /_/ |_|\__,_/____/\__/ - /_/ diff --git a/ct/headers/zigbee2mqtt b/ct/headers/zigbee2mqtt new file mode 100644 index 00000000..f6925a01 --- /dev/null +++ b/ct/headers/zigbee2mqtt @@ -0,0 +1,6 @@ + _____ _ __ ___ __ _______ ____________ +/__ / (_)___ _/ /_ ___ ___ |__ \ / |/ / __ \/_ __/_ __/ + / / / / __ `/ __ \/ _ \/ _ \__/ // /|_/ / / / / / / / / + / /__/ / /_/ / /_/ / __/ __/ __// / / / /_/ / / / / / +/____/_/\__, /_.___/\___/\___/____/_/ /_/\___\_\/_/ /_/ + /____/ From c3b675ad7ff996589e64dd653de1eb3d4cec3d55 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 2 Jul 2025 09:39:57 +0200 Subject: [PATCH 128/463] Update zigbee2mqtt.sh --- ct/zigbee2mqtt.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 29c52eec..f087d75b 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -39,6 +39,10 @@ function update_script() { RELEASE=$(curl -fsSL https://api.github.com/repos/Koenkk/zigbee2mqtt/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') if [[ "$RELEASE" != "$CURRENT" ]]; then + if ! command -v jq &>/dev/null; then + $STD apt-get update + $STD apt-get install -y jq + fi NODE_VERSION=24 NODE_MODULE="pnpm@$(curl -fsSL https://raw.githubusercontent.com/Koenkk/zigbee2mqtt/master/package.json | jq -r '.packageManager | split("@")[1]')" setup_nodejs msg_info "Stopping Service" From 6a6c1352afb8384e48ce6052d99beede84d989d8 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:04:22 +0200 Subject: [PATCH 129/463] add --- frontend/public/json/hanko.json | 35 +++++++++++++++++++++++++++++++++ install/hanko-install.sh | 8 ++++---- 2 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 frontend/public/json/hanko.json diff --git a/frontend/public/json/hanko.json b/frontend/public/json/hanko.json new file mode 100644 index 00000000..d8628ad8 --- /dev/null +++ b/frontend/public/json/hanko.json @@ -0,0 +1,35 @@ +{ + "name": "Hanko", + "slug": "hanko", + "categories": [ + 21 + ], + "date_created": "2025-07-02", + "type": "ct", + "updateable": true, + "privileged": false, + "config_path": "/opt/hanko/.env", + "interface_port": 3000, + "documentation": "https://docs.hanko.io/", + "website": "https://hanko.io/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/hanko.svg", + "description": "Hanko is an open-source authentication solution providing passkey-first login with support for WebAuthn/FIDO2, biometrics and modern identity flows. Easy to self-host and integrate via API or widget.", + "install_methods": [ + { + "type": "default", + "script": "ct/hanko.sh", + "resources": { + "cpu": 1, + "ram": 1024, + "hdd": 2, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} diff --git a/install/hanko-install.sh b/install/hanko-install.sh index 5ca0d69c..96f2308c 100644 --- a/install/hanko-install.sh +++ b/install/hanko-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2025 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://hanko.io/ source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color From 367085eb52d5d1d4c816299fa211908fbff1004d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:14:21 +0200 Subject: [PATCH 130/463] Update alpine.sh --- ct/alpine.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine.sh b/ct/alpine.sh index 8d09d7b6..11972a3c 100644 --- a/ct/alpine.sh +++ b/ct/alpine.sh @@ -11,7 +11,7 @@ var_cpu="${var_cpu:-1}" var_ram="${var_ram:-512}" var_disk="${var_disk:-1}" var_os="${var_os:-alpine}" -var_version="${var_version:-3.21}" +var_version="${var_version:-3.22}" var_unprivileged="${var_unprivileged:-1}" header_info "$APP" From e90c270e36172a04bc0bfa24229d10c9d36339fa Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:14:54 +0200 Subject: [PATCH 131/463] add default jsons --- frontend/public/json/docspell.json | 35 ++++++++++++++++++++++++++ frontend/public/json/frigate.json | 35 ++++++++++++++++++++++++++ frontend/public/json/healthchecks.json | 35 ++++++++++++++++++++++++++ frontend/public/json/maxun.json | 35 ++++++++++++++++++++++++++ frontend/public/json/mealie.json | 35 ++++++++++++++++++++++++++ frontend/public/json/npmplus.json | 35 ++++++++++++++++++++++++++ frontend/public/json/postiz.json | 35 ++++++++++++++++++++++++++ frontend/public/json/saltmaster.json | 35 ++++++++++++++++++++++++++ frontend/public/json/wallabag.json | 35 ++++++++++++++++++++++++++ 9 files changed, 315 insertions(+) create mode 100644 frontend/public/json/docspell.json create mode 100644 frontend/public/json/frigate.json create mode 100644 frontend/public/json/healthchecks.json create mode 100644 frontend/public/json/maxun.json create mode 100644 frontend/public/json/mealie.json create mode 100644 frontend/public/json/npmplus.json create mode 100644 frontend/public/json/postiz.json create mode 100644 frontend/public/json/saltmaster.json create mode 100644 frontend/public/json/wallabag.json diff --git a/frontend/public/json/docspell.json b/frontend/public/json/docspell.json new file mode 100644 index 00000000..dbf8e95a --- /dev/null +++ b/frontend/public/json/docspell.json @@ -0,0 +1,35 @@ +{ + "name": "Docspell", + "slug": "docspell", + "categories": [ + 12 + ], + "date_created": "2025-07-02", + "type": "ct", + "updateable": true, + "privileged": false, + "config_path": "/opt/docspell/.env", + "interface_port": 3000, + "documentation": "https://docspell.io/", + "website": "https://docspell.io/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/docspell.svg", + "description": "Docspell is an open-source self-hosted application.", + "install_methods": [ + { + "type": "default", + "script": "ct/docspell.sh", + "resources": { + "cpu": 1, + "ram": 1024, + "hdd": 2, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} \ No newline at end of file diff --git a/frontend/public/json/frigate.json b/frontend/public/json/frigate.json new file mode 100644 index 00000000..b5a8d7d6 --- /dev/null +++ b/frontend/public/json/frigate.json @@ -0,0 +1,35 @@ +{ + "name": "Frigate", + "slug": "frigate", + "categories": [ + 15 + ], + "date_created": "2025-07-02", + "type": "ct", + "updateable": true, + "privileged": false, + "config_path": "/opt/frigate/.env", + "interface_port": 3000, + "documentation": "https://frigate.io/", + "website": "https://frigate.io/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/frigate.svg", + "description": "Frigate is an open-source self-hosted application.", + "install_methods": [ + { + "type": "default", + "script": "ct/frigate.sh", + "resources": { + "cpu": 1, + "ram": 1024, + "hdd": 2, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} \ No newline at end of file diff --git a/frontend/public/json/healthchecks.json b/frontend/public/json/healthchecks.json new file mode 100644 index 00000000..ac5f3fe2 --- /dev/null +++ b/frontend/public/json/healthchecks.json @@ -0,0 +1,35 @@ +{ + "name": "Healthchecks", + "slug": "healthchecks", + "categories": [ + 9 + ], + "date_created": "2025-07-02", + "type": "ct", + "updateable": true, + "privileged": false, + "config_path": "/opt/healthchecks/.env", + "interface_port": 3000, + "documentation": "https://healthchecks.io/", + "website": "https://healthchecks.io/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/healthchecks.svg", + "description": "Healthchecks is an open-source self-hosted application.", + "install_methods": [ + { + "type": "default", + "script": "ct/healthchecks.sh", + "resources": { + "cpu": 1, + "ram": 1024, + "hdd": 2, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} \ No newline at end of file diff --git a/frontend/public/json/maxun.json b/frontend/public/json/maxun.json new file mode 100644 index 00000000..7ed83e0d --- /dev/null +++ b/frontend/public/json/maxun.json @@ -0,0 +1,35 @@ +{ + "name": "Maxun", + "slug": "maxun", + "categories": [ + 0 + ], + "date_created": "2025-07-02", + "type": "ct", + "updateable": true, + "privileged": false, + "config_path": "/opt/maxun/.env", + "interface_port": 3000, + "documentation": "https://maxun.io/", + "website": "https://maxun.io/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/maxun.svg", + "description": "Maxun is an open-source self-hosted application.", + "install_methods": [ + { + "type": "default", + "script": "ct/maxun.sh", + "resources": { + "cpu": 1, + "ram": 1024, + "hdd": 2, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} \ No newline at end of file diff --git a/frontend/public/json/mealie.json b/frontend/public/json/mealie.json new file mode 100644 index 00000000..dbe8b4c4 --- /dev/null +++ b/frontend/public/json/mealie.json @@ -0,0 +1,35 @@ +{ + "name": "Mealie", + "slug": "mealie", + "categories": [ + 13 + ], + "date_created": "2025-07-02", + "type": "ct", + "updateable": true, + "privileged": false, + "config_path": "/opt/mealie/.env", + "interface_port": 3000, + "documentation": "https://mealie.io/", + "website": "https://mealie.io/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/mealie.svg", + "description": "Mealie is an open-source self-hosted application.", + "install_methods": [ + { + "type": "default", + "script": "ct/mealie.sh", + "resources": { + "cpu": 1, + "ram": 1024, + "hdd": 2, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} \ No newline at end of file diff --git a/frontend/public/json/npmplus.json b/frontend/public/json/npmplus.json new file mode 100644 index 00000000..fe1120ef --- /dev/null +++ b/frontend/public/json/npmplus.json @@ -0,0 +1,35 @@ +{ + "name": "Npmplus", + "slug": "npmplus", + "categories": [ + 20 + ], + "date_created": "2025-07-02", + "type": "ct", + "updateable": true, + "privileged": false, + "config_path": "/opt/npmplus/.env", + "interface_port": 3000, + "documentation": "https://npmplus.io/", + "website": "https://npmplus.io/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/npmplus.svg", + "description": "Npmplus is an open-source self-hosted application.", + "install_methods": [ + { + "type": "default", + "script": "ct/npmplus.sh", + "resources": { + "cpu": 1, + "ram": 1024, + "hdd": 2, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} \ No newline at end of file diff --git a/frontend/public/json/postiz.json b/frontend/public/json/postiz.json new file mode 100644 index 00000000..dfcb0f04 --- /dev/null +++ b/frontend/public/json/postiz.json @@ -0,0 +1,35 @@ +{ + "name": "Postiz", + "slug": "postiz", + "categories": [ + 20 + ], + "date_created": "2025-07-02", + "type": "ct", + "updateable": true, + "privileged": false, + "config_path": "/opt/postiz/.env", + "interface_port": 3000, + "documentation": "https://postiz.io/", + "website": "https://postiz.io/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/postiz.svg", + "description": "Postiz is an open-source self-hosted application.", + "install_methods": [ + { + "type": "default", + "script": "ct/postiz.sh", + "resources": { + "cpu": 1, + "ram": 1024, + "hdd": 2, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} \ No newline at end of file diff --git a/frontend/public/json/saltmaster.json b/frontend/public/json/saltmaster.json new file mode 100644 index 00000000..b538aae1 --- /dev/null +++ b/frontend/public/json/saltmaster.json @@ -0,0 +1,35 @@ +{ + "name": "Saltmaster", + "slug": "saltmaster", + "categories": [ + 1 + ], + "date_created": "2025-07-02", + "type": "ct", + "updateable": true, + "privileged": false, + "config_path": "/opt/saltmaster/.env", + "interface_port": 3000, + "documentation": "https://saltmaster.io/", + "website": "https://saltmaster.io/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/saltmaster.svg", + "description": "Saltmaster is an open-source self-hosted application.", + "install_methods": [ + { + "type": "default", + "script": "ct/saltmaster.sh", + "resources": { + "cpu": 1, + "ram": 1024, + "hdd": 2, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} \ No newline at end of file diff --git a/frontend/public/json/wallabag.json b/frontend/public/json/wallabag.json new file mode 100644 index 00000000..203595a1 --- /dev/null +++ b/frontend/public/json/wallabag.json @@ -0,0 +1,35 @@ +{ + "name": "Wallabag", + "slug": "wallabag", + "categories": [ + 12 + ], + "date_created": "2025-07-02", + "type": "ct", + "updateable": true, + "privileged": false, + "config_path": "/opt/wallabag/.env", + "interface_port": 3000, + "documentation": "https://wallabag.io/", + "website": "https://wallabag.io/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/wallabag.svg", + "description": "Wallabag is an open-source self-hosted application.", + "install_methods": [ + { + "type": "default", + "script": "ct/wallabag.sh", + "resources": { + "cpu": 1, + "ram": 1024, + "hdd": 2, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} \ No newline at end of file From 55a67fdebac14caba61dd4b16092a525bb3f2b98 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:20:04 +0200 Subject: [PATCH 132/463] Delete npmplus.json --- frontend/public/json/npmplus.json | 35 ------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 frontend/public/json/npmplus.json diff --git a/frontend/public/json/npmplus.json b/frontend/public/json/npmplus.json deleted file mode 100644 index fe1120ef..00000000 --- a/frontend/public/json/npmplus.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "Npmplus", - "slug": "npmplus", - "categories": [ - 20 - ], - "date_created": "2025-07-02", - "type": "ct", - "updateable": true, - "privileged": false, - "config_path": "/opt/npmplus/.env", - "interface_port": 3000, - "documentation": "https://npmplus.io/", - "website": "https://npmplus.io/", - "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/npmplus.svg", - "description": "Npmplus is an open-source self-hosted application.", - "install_methods": [ - { - "type": "default", - "script": "ct/npmplus.sh", - "resources": { - "cpu": 1, - "ram": 1024, - "hdd": 2, - "os": "Debian", - "version": "12" - } - } - ], - "default_credentials": { - "username": null, - "password": null - }, - "notes": [] -} \ No newline at end of file From 6452e32525325a792ff9268524eefc0bccc6d827 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Wed, 2 Jul 2025 12:40:46 +0000 Subject: [PATCH 133/463] Update versions.json (#671) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 115 ++++++++++++++++++----------- 1 file changed, 70 insertions(+), 45 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index d0529c98..5cc7311b 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,49 @@ [ + { + "name": "wazuh/wazuh", + "version": "coverity-w27-4.13.0", + "date": "2025-07-01T03:17:32Z" + }, + { + "name": "glpi-project/glpi", + "version": "10.0.18", + "date": "2025-02-12T11:07:02Z" + }, + { + "name": "emqx/emqx", + "version": "e5.9.1", + "date": "2025-07-02T08:11:50Z" + }, + { + "name": "apache/tomcat", + "version": "9.0.107", + "date": "2025-07-02T07:12:09Z" + }, + { + "name": "nzbgetcom/nzbget", + "version": "v25.1", + "date": "2025-06-27T09:14:14Z" + }, + { + "name": "qbittorrent/qBittorrent", + "version": "release-5.1.2", + "date": "2025-07-02T06:13:16Z" + }, + { + "name": "home-assistant/core", + "version": "2025.6.3", + "date": "2025-06-24T13:00:12Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2107", + "date": "2025-07-02T05:53:02Z" + }, + { + "name": "firefly-iii/firefly-iii", + "version": "v6.2.20", + "date": "2025-07-02T04:03:37Z" + }, { "name": "diced/zipline", "version": "v4.2.0", @@ -24,21 +69,11 @@ "version": "1.2.35", "date": "2025-07-01T21:37:20Z" }, - { - "name": "apache/tomcat", - "version": "10.1.43", - "date": "2025-07-01T21:32:34Z" - }, { "name": "actualbudget/actual", "version": "v25.7.0", "date": "2025-07-01T21:02:27Z" }, - { - "name": "home-assistant/core", - "version": "2025.6.3", - "date": "2025-06-24T13:00:12Z" - }, { "name": "TwiN/gatus", "version": "v5.19.0", @@ -49,6 +84,11 @@ "version": "2.5.0", "date": "2025-07-01T18:28:01Z" }, + { + "name": "keycloak/keycloak", + "version": "26.3.0", + "date": "2025-07-01T13:18:12Z" + }, { "name": "hivemq/hivemq-community-edition", "version": "2025.4", @@ -74,11 +114,6 @@ "version": "v1.133.0", "date": "2025-07-01T15:13:42Z" }, - { - "name": "keycloak/keycloak", - "version": "26.3.0", - "date": "2025-07-01T13:18:12Z" - }, { "name": "syncthing/syncthing", "version": "v1.30.0", @@ -94,11 +129,6 @@ "version": "v99.99.99", "date": "2025-07-01T08:26:41Z" }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2101", - "date": "2025-07-01T05:56:59Z" - }, { "name": "zabbix/zabbix", "version": "7.4.0", @@ -109,11 +139,6 @@ "version": "v0.15.0-rc3", "date": "2025-07-01T04:09:37Z" }, - { - "name": "wazuh/wazuh", - "version": "coverity-w27-4.13.0", - "date": "2025-07-01T03:17:32Z" - }, { "name": "NginxProxyManager/nginx-proxy-manager", "version": "v2.12.4", @@ -189,21 +214,11 @@ "version": "v29.0", "date": "2025-06-30T03:52:33Z" }, - { - "name": "firefly-iii/firefly-iii", - "version": "v6.2.19", - "date": "2025-06-28T06:53:45Z" - }, { "name": "dgtlmoon/changedetection.io", "version": "0.50.5", "date": "2025-06-29T08:54:47Z" }, - { - "name": "emqx/emqx", - "version": "e5.9.1-rc.1", - "date": "2025-06-29T07:27:21Z" - }, { "name": "theonedev/onedev", "version": "v11.11.2", @@ -269,11 +284,6 @@ "version": "flowise@3.0.3", "date": "2025-06-27T09:53:57Z" }, - { - "name": "nzbgetcom/nzbget", - "version": "v25.1", - "date": "2025-06-27T09:14:14Z" - }, { "name": "cockpit-project/cockpit", "version": "341.1", @@ -409,11 +419,6 @@ "version": "2025.6.22", "date": "2025-06-22T22:41:11Z" }, - { - "name": "qbittorrent/qBittorrent", - "version": "release-5.1.1", - "date": "2025-06-22T21:41:17Z" - }, { "name": "clusterzx/paperless-ai", "version": "v3.0.7", @@ -468,5 +473,25 @@ "name": "icereed/paperless-gpt", "version": "v0.21.0", "date": "2025-06-19T11:54:59Z" + }, + { + "name": "neo4j/neo4j", + "version": "2025.05.1", + "date": "2025-06-19T11:28:36Z" + }, + { + "name": "redis/redis", + "version": "8.2-m01-int2", + "date": "2025-06-12T08:52:10Z" + }, + { + "name": "prometheus-pve/prometheus-pve-exporter", + "version": "v3.5.5", + "date": "2025-06-19T05:43:47Z" + }, + { + "name": "ipfs/kubo", + "version": "v0.35.0", + "date": "2025-05-21T18:00:32Z" } ] From 62342f3f8839fd8ba65c9aa40808b6ba8fe9622a Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Thu, 3 Jul 2025 01:39:49 +0000 Subject: [PATCH 134/463] Update versions.json (#672) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 194 ++++++++++++----------------- 1 file changed, 82 insertions(+), 112 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 5cc7311b..ace9471b 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,84 @@ [ + { + "name": "esphome/esphome", + "version": "2025.6.3", + "date": "2025-07-03T01:07:26Z" + }, + { + "name": "actualbudget/actual", + "version": "v25.7.1", + "date": "2025-07-03T01:03:18Z" + }, + { + "name": "mongodb/mongo", + "version": "r6.0.25-rc0", + "date": "2025-07-03T00:44:52Z" + }, + { + "name": "documenso/documenso", + "version": "v1.12.2-rc.0", + "date": "2025-07-03T00:31:22Z" + }, + { + "name": "cross-seed/cross-seed", + "version": "v6.12.7", + "date": "2025-06-18T03:44:24Z" + }, + { + "name": "emqx/emqx", + "version": "v5.8.7", + "date": "2025-07-02T21:54:54Z" + }, + { + "name": "hargata/lubelog", + "version": "v1.4.8", + "date": "2025-07-02T21:15:13Z" + }, + { + "name": "Koenkk/zigbee2mqtt", + "version": "2.5.1", + "date": "2025-07-02T19:38:06Z" + }, + { + "name": "redis/redis", + "version": "8.2-rc1-int", + "date": "2025-07-02T19:27:08Z" + }, + { + "name": "keycloak/keycloak", + "version": "26.2.5", + "date": "2025-05-28T06:49:43Z" + }, + { + "name": "ollama/ollama", + "version": "v0.9.5", + "date": "2025-07-02T18:39:28Z" + }, + { + "name": "firefly-iii/firefly-iii", + "version": "v6.2.20", + "date": "2025-07-02T04:03:37Z" + }, + { + "name": "home-assistant/core", + "version": "2025.7.0", + "date": "2025-07-02T16:23:42Z" + }, + { + "name": "fuma-nama/fumadocs", + "version": "fumadocs-core@15.6.1", + "date": "2025-07-02T15:29:41Z" + }, + { + "name": "nzbgetcom/nzbget", + "version": "v25.1", + "date": "2025-06-27T09:14:14Z" + }, + { + "name": "Graylog2/graylog2-server", + "version": "6.2.5", + "date": "2025-07-02T13:06:30Z" + }, { "name": "wazuh/wazuh", "version": "coverity-w27-4.13.0", @@ -9,41 +89,21 @@ "version": "10.0.18", "date": "2025-02-12T11:07:02Z" }, - { - "name": "emqx/emqx", - "version": "e5.9.1", - "date": "2025-07-02T08:11:50Z" - }, { "name": "apache/tomcat", "version": "9.0.107", "date": "2025-07-02T07:12:09Z" }, - { - "name": "nzbgetcom/nzbget", - "version": "v25.1", - "date": "2025-06-27T09:14:14Z" - }, { "name": "qbittorrent/qBittorrent", "version": "release-5.1.2", "date": "2025-07-02T06:13:16Z" }, - { - "name": "home-assistant/core", - "version": "2025.6.3", - "date": "2025-06-24T13:00:12Z" - }, { "name": "Jackett/Jackett", "version": "v0.22.2107", "date": "2025-07-02T05:53:02Z" }, - { - "name": "firefly-iii/firefly-iii", - "version": "v6.2.20", - "date": "2025-07-02T04:03:37Z" - }, { "name": "diced/zipline", "version": "v4.2.0", @@ -59,36 +119,16 @@ "version": "2.1.1", "date": "2025-06-14T17:45:06Z" }, - { - "name": "mongodb/mongo", - "version": "r8.1.2", - "date": "2025-07-01T22:39:32Z" - }, { "name": "Threadfin/Threadfin", "version": "1.2.35", "date": "2025-07-01T21:37:20Z" }, - { - "name": "actualbudget/actual", - "version": "v25.7.0", - "date": "2025-07-01T21:02:27Z" - }, { "name": "TwiN/gatus", "version": "v5.19.0", "date": "2025-07-01T19:59:32Z" }, - { - "name": "Koenkk/zigbee2mqtt", - "version": "2.5.0", - "date": "2025-07-01T18:28:01Z" - }, - { - "name": "keycloak/keycloak", - "version": "26.3.0", - "date": "2025-07-01T13:18:12Z" - }, { "name": "hivemq/hivemq-community-edition", "version": "2025.4", @@ -159,11 +199,6 @@ "version": "v0.9.81", "date": "2025-06-30T16:40:33Z" }, - { - "name": "ollama/ollama", - "version": "v0.9.4-rc6", - "date": "2025-06-30T15:59:03Z" - }, { "name": "prometheus/prometheus", "version": "v2.53.5", @@ -179,31 +214,16 @@ "version": "v7.4.4", "date": "2025-06-30T13:04:22Z" }, - { - "name": "Graylog2/graylog2-server", - "version": "6.3.0", - "date": "2025-06-30T11:26:45Z" - }, { "name": "grokability/snipe-it", "version": "v8.1.17", "date": "2025-06-30T11:26:27Z" }, - { - "name": "documenso/documenso", - "version": "v1.12.0-rc.8", - "date": "2025-06-30T09:47:37Z" - }, { "name": "PrivateBin/PrivateBin", "version": "1.7.8", "date": "2025-06-30T09:00:54Z" }, - { - "name": "fuma-nama/fumadocs", - "version": "fumadocs-mdx@11.6.10", - "date": "2025-06-30T07:07:36Z" - }, { "name": "mattermost/mattermost", "version": "preview-v0.1", @@ -239,11 +259,6 @@ "version": "3.1.0", "date": "2025-06-28T09:02:38Z" }, - { - "name": "esphome/esphome", - "version": "2025.6.2", - "date": "2025-06-28T03:47:16Z" - }, { "name": "plexguide/Huntarr.io", "version": "8.1.11", @@ -401,8 +416,8 @@ }, { "name": "runtipi/runtipi", - "version": "v4.2.1", - "date": "2025-06-03T20:04:28Z" + "version": "nightly", + "date": "2025-06-23T19:10:33Z" }, { "name": "VictoriaMetrics/VictoriaMetrics", @@ -448,50 +463,5 @@ "name": "go-gitea/gitea", "version": "v1.24.2", "date": "2025-06-20T20:37:55Z" - }, - { - "name": "immich-app/immich", - "version": "v1.135.3", - "date": "2025-06-20T20:19:20Z" - }, - { - "name": "Sonarr/Sonarr", - "version": "v4.0.15.2941", - "date": "2025-06-20T17:20:54Z" - }, - { - "name": "benzino77/tasmocompiler", - "version": "v12.7.0", - "date": "2025-06-20T08:31:16Z" - }, - { - "name": "paperless-ngx/paperless-ngx", - "version": "v2.17.1", - "date": "2025-06-19T19:35:01Z" - }, - { - "name": "icereed/paperless-gpt", - "version": "v0.21.0", - "date": "2025-06-19T11:54:59Z" - }, - { - "name": "neo4j/neo4j", - "version": "2025.05.1", - "date": "2025-06-19T11:28:36Z" - }, - { - "name": "redis/redis", - "version": "8.2-m01-int2", - "date": "2025-06-12T08:52:10Z" - }, - { - "name": "prometheus-pve/prometheus-pve-exporter", - "version": "v3.5.5", - "date": "2025-06-19T05:43:47Z" - }, - { - "name": "ipfs/kubo", - "version": "v0.35.0", - "date": "2025-05-21T18:00:32Z" } ] From c94764b5f592911415ebcd6fb8af6a139e546279 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 09:05:57 +0200 Subject: [PATCH 135/463] Update debian-install.sh --- install/debian-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/debian-install.sh b/install/debian-install.sh index 16287231..e0c5422a 100644 --- a/install/debian-install.sh +++ b/install/debian-install.sh @@ -41,7 +41,7 @@ msg_ok "Installed Dependencies" #NODE_MODULE="pnpm@10.1,yarn" #RELEASE=$(curl_handler -fsSL https://api.github.com/repos/babybuddy/babybuddy/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') #msg_ok "Get Release $RELEASE" -#NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs +NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs #PG_VERSION="16" setup_postgresql #MARIADB_VERSION="11.8" From c010ab3799d1e788318634b547568fd8faf163d7 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 09:06:28 +0200 Subject: [PATCH 136/463] Update debian-install.sh --- install/debian-install.sh | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/install/debian-install.sh b/install/debian-install.sh index e0c5422a..a684ac06 100644 --- a/install/debian-install.sh +++ b/install/debian-install.sh @@ -24,16 +24,6 @@ msg_ok "Installed Dependencies" #PYTHON_VERSION="3.12" setup_uv -#echo -e "fetching healthchecks" -#fetch_and_deploy_gh_release "healthchecks" "healthchecks/healthchecks" "tarball" "latest" "/opt/healthchecks" -# minimal call: fetch_and_deploy_gh_release "healthchecks" "healthchecks/healthchecks" "tarball" -#echo -e "healthchecks done" - -#echo -e "fetching defguard" -#fetch_and_deploy_gh_release "defguard" "DefGuard/defguard" "binary" "latest" "/opt/defguard" -# minimal call: fetch_and_deploy_gh_release "defguard" "DefGuard/defguard" "binary" -#echo -e "defguard done" - #PHP_VERSION=8.2 PHP_FPM=YES setup_php #setup_composer @@ -44,17 +34,6 @@ msg_ok "Installed Dependencies" NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs #PG_VERSION="16" setup_postgresql -#MARIADB_VERSION="11.8" -#MYSQL_VERSION="8.0" - -#install_mongodb -#setup_postgresql -#setup_mariadb -#install_mysql - -# msg_info "Setup DISTRO env" -# DISTRO="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" -# msg_ok "Setup DISTRO" motd_ssh customize From ca1d746c17473438cdd9315c15c2e47175b19e2d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 10:21:55 +0200 Subject: [PATCH 137/463] Update build.func --- misc/build.func | 59 +++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/misc/build.func b/misc/build.func index bc384860..bd6b9453 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1202,7 +1202,9 @@ build_container() { exit $RET fi - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + LXC_CONFIG="/etc/pve/lxc/${CTID}.conf" + + # USB passthrough for privileged LXC (CT_TYPE=0) if [ "$CT_TYPE" == "0" ]; then cat <>"$LXC_CONFIG" # USB passthrough @@ -1218,36 +1220,35 @@ lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create= EOF fi - if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then - cat <>$LXC_CONFIG -# VAAPI hardware transcoding -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file -EOF - fi - else - if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then - if [[ -e "/dev/dri/renderD128" ]]; then - if [[ -e "/dev/dri/card0" ]]; then - cat <>$LXC_CONFIG -# VAAPI hardware transcoding -dev0: /dev/dri/card0,gid=44 -dev1: /dev/dri/renderD128,gid=104 -EOF - else - cat <>"$LXC_CONFIG" -# VAAPI hardware transcoding -dev0: /dev/dri/card1,gid=44 -dev1: /dev/dri/renderD128,gid=104 -EOF - fi + # VAAPI passthrough for known apps on privileged LXC + VAAPI_APPS="immich Channels Emby ErsatzTV Frigate Jellyfin Plex Scrypted Tdarr Unmanic Ollama FileFlows" + + if [ "$CT_TYPE" == "0" ] && [[ " $VAAPI_APPS " =~ " $APP " ]]; then + echo -e "\n⚙️ VAAPI passthrough configuration for LXC container:" + if [[ -e /dev/dri/renderD128 ]]; then + read -rp " ➤ /dev/dri/renderD128 found – mount into container? [y/N]: " MOUNT_D128 + if [[ "$MOUNT_D128" =~ ^[Yy]$ ]]; then + echo "lxc.cgroup2.devices.allow: c 226:128 rwm" >>"$LXC_CONFIG" + echo "lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file" >>"$LXC_CONFIG" fi fi + if [[ -e /dev/dri/card0 ]]; then + read -rp " ➤ /dev/dri/card0 found – mount into container? [y/N]: " MOUNT_CARD0 + if [[ "$MOUNT_CARD0" =~ ^[Yy]$ ]]; then + echo "lxc.cgroup2.devices.allow: c 226:0 rwm" >>"$LXC_CONFIG" + echo "lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file" >>"$LXC_CONFIG" + fi + fi + if [[ -e /dev/fb0 ]]; then + read -rp " ➤ /dev/fb0 (framebuffer) found – mount as well? [y/N]: " MOUNT_FB0 + if [[ "$MOUNT_FB0" =~ ^[Yy]$ ]]; then + echo "lxc.cgroup2.devices.allow: c 29:0 rwm" >>"$LXC_CONFIG" + echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >>"$LXC_CONFIG" + fi + fi + if [[ -d /dev/dri ]]; then + echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG" + fi fi if [ "$ENABLE_TUN" == "yes" ]; then From 3aa28f64295c0be3812c72b53e3d00d954d8a369 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 10:22:47 +0200 Subject: [PATCH 138/463] testing --- ct/openwebui.sh | 81 +++++++++++++++++++++++++++++ install/openwebui-install.sh | 99 ++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 ct/openwebui.sh create mode 100644 install/openwebui-install.sh diff --git a/ct/openwebui.sh b/ct/openwebui.sh new file mode 100644 index 00000000..86707daf --- /dev/null +++ b/ct/openwebui.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 tteck +# Author: havardthom +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://openwebui.com/ + +APP="Open WebUI" +var_tags="${var_tags:-ai;interface}" +var_cpu="${var_cpu:-4}" +var_ram="${var_ram:-8192}" +var_disk="${var_disk:-25}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +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/open-webui ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + if [ -x "/usr/bin/ollama" ]; then + msg_info "Updating Ollama" + OLLAMA_VERSION=$(ollama -v | awk '{print $NF}') + RELEASE=$(curl -s https://api.github.com/repos/ollama/ollama/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4)}') + if [ "$OLLAMA_VERSION" != "$RELEASE" ]; then + rm -rf /usr/lib/ollama + rm -rf /usr/bin/ollama + curl -fsSLO https://ollama.com/download/ollama-linux-amd64.tgz + tar -C /usr -xzf ollama-linux-amd64.tgz + rm -rf ollama-linux-amd64.tgz + msg_ok "Ollama updated to version $RELEASE" + else + msg_ok "Ollama is already up to date." + fi + fi + + msg_info "Updating ${APP} (Patience)" + cd /opt/open-webui + mkdir -p /opt/open-webui-backup + cp -rf /opt/open-webui/backend/data /opt/open-webui-backup + git add -A + $STD git stash + $STD git reset --hard + output=$(git pull --no-rebase) + if echo "$output" | grep -q "Already up to date."; then + msg_ok "$APP is already up to date." + exit + fi + systemctl stop open-webui.service + $STD npm install + export NODE_OPTIONS="--max-old-space-size=3584" + $STD npm run build + cd ./backend + $STD pip install -r requirements.txt -U + cp -rf /opt/open-webui-backup/* /opt/open-webui/backend + if git stash list | grep -q 'stash@{'; then + $STD git stash pop + fi + systemctl start open-webui.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}:8080${CL}" diff --git a/install/openwebui-install.sh b/install/openwebui-install.sh new file mode 100644 index 00000000..af2b3611 --- /dev/null +++ b/install/openwebui-install.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 tteck +# Author: tteck +# Co-Author: havardthom +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://openwebui.com/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + git \ + ffmpeg +msg_ok "Installed Dependencies" + +msg_info "Setup Python3" +$STD apt-get install -y --no-install-recommends \ + python3 \ + python3-pip +msg_ok "Setup Python3" + +NODE_VERSION="22" setup_nodejs + +msg_info "Installing Open WebUI (Patience)" +$STD git clone https://github.com/open-webui/open-webui.git /opt/open-webui +cd /opt/open-webui/backend +$STD pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu +$STD pip3 install -r requirements.txt -U +cd /opt/open-webui +cp .env.example .env +cat </opt/open-webui/.env +ENV=prod +ENABLE_OLLAMA_API=false +OLLAMA_BASE_URL=http://0.0.0.0:11434 +EOF +$STD npm install +export NODE_OPTIONS="--max-old-space-size=3584" +$STD npm run build +msg_ok "Installed Open WebUI" + +read -r -p "${TAB3}Would you like to add Ollama? " prompt +if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + msg_info "Installing Ollama" + curl -fsSLO https://ollama.com/download/ollama-linux-amd64.tgz + tar -C /usr -xzf ollama-linux-amd64.tgz + rm -rf ollama-linux-amd64.tgz + cat </etc/systemd/system/ollama.service +[Unit] +Description=Ollama Service +After=network-online.target + +[Service] +Type=exec +ExecStart=/usr/bin/ollama serve +Environment=HOME=$HOME +Environment=OLLAMA_HOST=0.0.0.0 +Restart=always +RestartSec=3 + +[Install] +WantedBy=multi-user.target +EOF + systemctl enable -q --now ollama + sed -i 's/ENABLE_OLLAMA_API=false/ENABLE_OLLAMA_API=true/g' /opt/open-webui/.env + msg_ok "Installed Ollama" +fi + +msg_info "Creating Service" +cat </etc/systemd/system/open-webui.service +[Unit] +Description=Open WebUI Service +After=network.target + +[Service] +Type=exec +WorkingDirectory=/opt/open-webui +EnvironmentFile=/opt/open-webui/.env +ExecStart=/opt/open-webui/backend/start.sh + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now open-webui +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 0e5a3f18934b035fec47bdd5bd49083d2329e556 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Thu, 3 Jul 2025 08:23:19 +0000 Subject: [PATCH 139/463] Update .app files (#673) Co-authored-by: GitHub Actions --- ct/headers/openwebui | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ct/headers/openwebui diff --git a/ct/headers/openwebui b/ct/headers/openwebui new file mode 100644 index 00000000..0097a279 --- /dev/null +++ b/ct/headers/openwebui @@ -0,0 +1,6 @@ + ____ _ __ __ __ ______ + / __ \____ ___ ____ | | / /__ / /_ / / / / _/ + / / / / __ \/ _ \/ __ \ | | /| / / _ \/ __ \/ / / // / +/ /_/ / /_/ / __/ / / / | |/ |/ / __/ /_/ / /_/ // / +\____/ .___/\___/_/ /_/ |__/|__/\___/_.___/\____/___/ + /_/ From 2e7f7bda90db859e38e21f6fb9ed5b096aee6833 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 10:25:59 +0200 Subject: [PATCH 140/463] Update build.func --- misc/build.func | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/misc/build.func b/misc/build.func index bd6b9453..68e0865b 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1221,9 +1221,31 @@ EOF fi # VAAPI passthrough for known apps on privileged LXC - VAAPI_APPS="immich Channels Emby ErsatzTV Frigate Jellyfin Plex Scrypted Tdarr Unmanic Ollama FileFlows" + VAAPI_APPS=( + "immich" + "Channels" + "Emby" + "ErsatzTV" + "Frigate" + "Jellyfin" + "Plex" + "Scrypted" + "Tdarr" + "Unmanic" + "Ollama" + "FileFlows" + "Open WebUI" + ) - if [ "$CT_TYPE" == "0" ] && [[ " $VAAPI_APPS " =~ " $APP " ]]; then + is_vaapi_app=false + for vaapi_app in "${VAAPI_APPS[@]}"; do + if [[ "$APP" == "$vaapi_app" ]]; then + is_vaapi_app=true + break + fi + done + + if [ "$CT_TYPE" == "0" ] && [ "$is_vaapi_app" == "true" ]; then echo -e "\n⚙️ VAAPI passthrough configuration for LXC container:" if [[ -e /dev/dri/renderD128 ]]; then read -rp " ➤ /dev/dri/renderD128 found – mount into container? [y/N]: " MOUNT_D128 From b25aea86a00b7e1f5b4ef26289190866f256d521 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 10:34:37 +0200 Subject: [PATCH 141/463] Update build.func --- misc/build.func | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 68e0865b..c1e96e84 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1245,8 +1245,12 @@ EOF fi done - if [ "$CT_TYPE" == "0" ] && [ "$is_vaapi_app" == "true" ]; then + if [ "$CT_TYPE" == "0" ] || [ "$is_vaapi_app" == "true" ]; then echo -e "\n⚙️ VAAPI passthrough configuration for LXC container:" + + if [ "$CT_TYPE" != "0" ]; then + echo "⚠️ Container is unprivileged – VAAPI passthrough may not work depending on host configuration." + fi if [[ -e /dev/dri/renderD128 ]]; then read -rp " ➤ /dev/dri/renderD128 found – mount into container? [y/N]: " MOUNT_D128 if [[ "$MOUNT_D128" =~ ^[Yy]$ ]]; then From 8382fea9b2d212c8ddbce07b43443924fd235db3 Mon Sep 17 00:00:00 2001 From: Tobias <96661824+CrazyWolf13@users.noreply.github.com> Date: Thu, 3 Jul 2025 10:51:22 +0200 Subject: [PATCH 142/463] Create vikunja.sh --- ct/vikunja.sh | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ct/vikunja.sh diff --git a/ct/vikunja.sh b/ct/vikunja.sh new file mode 100644 index 00000000..1e50e674 --- /dev/null +++ b/ct/vikunja.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (Canbiz) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://vikunja.io/ + +APP="Vikunja" +var_tags="${var_tags:-todo-app}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-1024}" +var_disk="${var_disk:-4}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +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/vikunja ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + RELEASE=$(curl -fsSL https://dl.vikunja.io/vikunja/ | grep -oP 'href="/vikunja/\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n 1) + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + msg_info "Stopping ${APP}" + systemctl stop vikunja + msg_ok "Stopped ${APP}" + + msg_info "Updating ${APP} to ${RELEASE}" + cd /opt + rm -rf /opt/vikunja/vikunja + curl -fsSL "https://dl.vikunja.io/vikunja/$RELEASE/vikunja-$RELEASE-amd64.deb" -o $(basename "https://dl.vikunja.io/vikunja/$RELEASE/vikunja-$RELEASE-amd64.deb") + export DEBIAN_FRONTEND=noninteractive + $STD dpkg -i vikunja-$RELEASE-amd64.deb + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Updated ${APP}" + + msg_info "Starting ${APP}" + systemctl start vikunja + msg_ok "Started ${APP}" + + msg_info "Cleaning Up" + rm -rf /opt/vikunja-$RELEASE-amd64.deb + msg_ok "Cleaned" + msg_ok "Updated Successfully" + else + msg_ok "No update required. ${APP} is already at ${RELEASE}" + 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}http://${IP}:3456${CL}" From c451629a0902d95b453ab5629e6b4f734b622425 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 10:51:24 +0200 Subject: [PATCH 143/463] Update build.func --- misc/build.func | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index c1e96e84..0fc1da11 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1245,7 +1245,8 @@ EOF fi done - if [ "$CT_TYPE" == "0" ] || [ "$is_vaapi_app" == "true" ]; then + if ([ "$CT_TYPE" == "0" ] || [ "$is_vaapi_app" == "true" ]) && + ([[ -e /dev/dri/renderD128 ]] || [[ -e /dev/dri/card0 ]] || [[ -e /dev/fb0 ]]); then echo -e "\n⚙️ VAAPI passthrough configuration for LXC container:" if [ "$CT_TYPE" != "0" ]; then From 5a2407eb87971680697e7fdb993f52c221f136b1 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Thu, 3 Jul 2025 08:51:45 +0000 Subject: [PATCH 144/463] Update .app files (#674) Co-authored-by: GitHub Actions --- ct/headers/vikunja | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ct/headers/vikunja diff --git a/ct/headers/vikunja b/ct/headers/vikunja new file mode 100644 index 00000000..afd006f1 --- /dev/null +++ b/ct/headers/vikunja @@ -0,0 +1,6 @@ + _ ___ __ _ +| | / (_) /____ ______ (_)___ _ +| | / / / //_/ / / / __ \ / / __ `/ +| |/ / / ,< / /_/ / / / / / / /_/ / +|___/_/_/|_|\__,_/_/ /_/_/ /\__,_/ + /___/ From b6d9f74e6f89368877f625dc6b0fe7db49daf9ea Mon Sep 17 00:00:00 2001 From: Tobias <96661824+CrazyWolf13@users.noreply.github.com> Date: Thu, 3 Jul 2025 10:51:47 +0200 Subject: [PATCH 145/463] Create vikunja-install.sh --- install/vikunja-install.sh | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 install/vikunja-install.sh diff --git a/install/vikunja-install.sh b/install/vikunja-install.sh new file mode 100644 index 00000000..f56d073d --- /dev/null +++ b/install/vikunja-install.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (Canbiz) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://vikunja.io/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y make +msg_ok "Installed Dependencies" + +msg_info "Setup Vikunja (Patience)" +cd /opt +RELEASE=$(curl -fsSL https://dl.vikunja.io/vikunja/ | grep -oP 'href="/vikunja/\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n 1) +curl -fsSL "https://dl.vikunja.io/vikunja/$RELEASE/vikunja-$RELEASE-amd64.deb" -o vikunja-$RELEASE-amd64.deb +$STD dpkg -i vikunja-$RELEASE-amd64.deb +sed -i 's|^ timezone: .*| timezone: UTC|' /etc/vikunja/config.yml +sed -i 's|"./vikunja.db"|"/etc/vikunja/vikunja.db"|' /etc/vikunja/config.yml +sed -i 's|./files|/etc/vikunja/files|' /etc/vikunja/config.yml +systemctl start vikunja.service +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt +msg_ok "Installed Vikunja" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -rf /opt/vikunja-$RELEASE-amd64.deb +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 3438940e66773cab8827ab8848a298c4c4bb424f Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 10:53:13 +0200 Subject: [PATCH 146/463] Update build.func --- misc/build.func | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/misc/build.func b/misc/build.func index 0fc1da11..0c6210f9 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1220,7 +1220,7 @@ lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create= EOF fi - # VAAPI passthrough for known apps on privileged LXC + # VAAPI passthrough for privileged containers or known apps VAAPI_APPS=( "immich" "Channels" @@ -1247,11 +1247,13 @@ EOF if ([ "$CT_TYPE" == "0" ] || [ "$is_vaapi_app" == "true" ]) && ([[ -e /dev/dri/renderD128 ]] || [[ -e /dev/dri/card0 ]] || [[ -e /dev/fb0 ]]); then - echo -e "\n⚙️ VAAPI passthrough configuration for LXC container:" + + msg_custom "⚙️" "\e[36m" "VAAPI passthrough configuration for LXC container" if [ "$CT_TYPE" != "0" ]; then - echo "⚠️ Container is unprivileged – VAAPI passthrough may not work depending on host configuration." + msg_custom "⚠️" "\e[33m" "Container is unprivileged – VAAPI passthrough may not work depending on host configuration." fi + if [[ -e /dev/dri/renderD128 ]]; then read -rp " ➤ /dev/dri/renderD128 found – mount into container? [y/N]: " MOUNT_D128 if [[ "$MOUNT_D128" =~ ^[Yy]$ ]]; then @@ -1259,6 +1261,7 @@ EOF echo "lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file" >>"$LXC_CONFIG" fi fi + if [[ -e /dev/dri/card0 ]]; then read -rp " ➤ /dev/dri/card0 found – mount into container? [y/N]: " MOUNT_CARD0 if [[ "$MOUNT_CARD0" =~ ^[Yy]$ ]]; then @@ -1266,6 +1269,7 @@ EOF echo "lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file" >>"$LXC_CONFIG" fi fi + if [[ -e /dev/fb0 ]]; then read -rp " ➤ /dev/fb0 (framebuffer) found – mount as well? [y/N]: " MOUNT_FB0 if [[ "$MOUNT_FB0" =~ ^[Yy]$ ]]; then @@ -1273,11 +1277,13 @@ EOF echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >>"$LXC_CONFIG" fi fi + if [[ -d /dev/dri ]]; then echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG" fi fi + # TUN device passthrough if [ "$ENABLE_TUN" == "yes" ]; then cat <>"$LXC_CONFIG" lxc.cgroup2.devices.allow: c 10:200 rwm From 52e7bbb0b3b8f894ef1c5e295ba3d2e77ca78751 Mon Sep 17 00:00:00 2001 From: Tobias <96661824+CrazyWolf13@users.noreply.github.com> Date: Thu, 3 Jul 2025 10:57:51 +0200 Subject: [PATCH 147/463] vikunja: add: unstable selector --- ct/vikunja.sh | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/ct/vikunja.sh b/ct/vikunja.sh index 1e50e674..e8979d12 100644 --- a/ct/vikunja.sh +++ b/ct/vikunja.sh @@ -27,12 +27,21 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi - RELEASE=$(curl -fsSL https://dl.vikunja.io/vikunja/ | grep -oP 'href="/vikunja/\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n 1) + + if whiptail --backtitle "Vikunja Update" --title "🔄 VERSION SELECTION" --yesno \ + "Choose the version type to update to:\n\n• STABLE: Recommended for production use\n• UNSTABLE: Latest development version\n\n⚠️ WARNING: Unstable versions may contain bugs,\nbe incomplete, or cause system instability.\nOnly use for testing purposes.\n\nDo you want to use the UNSTABLE version?\n(No = Stable, Yes = Unstable)" 16 70 --defaultno + then + RELEASE="unstable" + msg_info "Selected UNSTABLE version" + else + RELEASE=$(curl -fsSL https://dl.vikunja.io/vikunja/ | grep -oP 'href="/vikunja/\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n 1) + msg_info "Selected STABLE version: ${RELEASE}" + fi + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then msg_info "Stopping ${APP}" systemctl stop vikunja msg_ok "Stopped ${APP}" - msg_info "Updating ${APP} to ${RELEASE}" cd /opt rm -rf /opt/vikunja/vikunja @@ -41,11 +50,9 @@ function update_script() { $STD dpkg -i vikunja-$RELEASE-amd64.deb echo "${RELEASE}" >/opt/${APP}_version.txt msg_ok "Updated ${APP}" - msg_info "Starting ${APP}" systemctl start vikunja msg_ok "Started ${APP}" - msg_info "Cleaning Up" rm -rf /opt/vikunja-$RELEASE-amd64.deb msg_ok "Cleaned" From ed5b8271e16f3ba103b2a8a3c9bea7225a40defb Mon Sep 17 00:00:00 2001 From: Tobias <96661824+CrazyWolf13@users.noreply.github.com> Date: Thu, 3 Jul 2025 11:10:35 +0200 Subject: [PATCH 148/463] Update vikunja.sh --- ct/vikunja.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ct/vikunja.sh b/ct/vikunja.sh index e8979d12..621a470b 100644 --- a/ct/vikunja.sh +++ b/ct/vikunja.sh @@ -32,9 +32,11 @@ function update_script() { "Choose the version type to update to:\n\n• STABLE: Recommended for production use\n• UNSTABLE: Latest development version\n\n⚠️ WARNING: Unstable versions may contain bugs,\nbe incomplete, or cause system instability.\nOnly use for testing purposes.\n\nDo you want to use the UNSTABLE version?\n(No = Stable, Yes = Unstable)" 16 70 --defaultno then RELEASE="unstable" + FILENAME="vikunja-${RELEASE}-x86_64.deb" msg_info "Selected UNSTABLE version" else RELEASE=$(curl -fsSL https://dl.vikunja.io/vikunja/ | grep -oP 'href="/vikunja/\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n 1) + FILENAME="vikunja-${RELEASE}-amd64.deb" msg_info "Selected STABLE version: ${RELEASE}" fi @@ -45,16 +47,16 @@ function update_script() { msg_info "Updating ${APP} to ${RELEASE}" cd /opt rm -rf /opt/vikunja/vikunja - curl -fsSL "https://dl.vikunja.io/vikunja/$RELEASE/vikunja-$RELEASE-amd64.deb" -o $(basename "https://dl.vikunja.io/vikunja/$RELEASE/vikunja-$RELEASE-amd64.deb") + curl -fsSL "https://dl.vikunja.io/vikunja/$RELEASE/$FILENAME" -o $(basename "https://dl.vikunja.io/vikunja/$RELEASE/$FILENAME") export DEBIAN_FRONTEND=noninteractive - $STD dpkg -i vikunja-$RELEASE-amd64.deb + $STD dpkg -i $FILENAME echo "${RELEASE}" >/opt/${APP}_version.txt msg_ok "Updated ${APP}" msg_info "Starting ${APP}" systemctl start vikunja msg_ok "Started ${APP}" msg_info "Cleaning Up" - rm -rf /opt/vikunja-$RELEASE-amd64.deb + rm -rf /opt/$FILENAME msg_ok "Cleaned" msg_ok "Updated Successfully" else From 4f18d5c1c412ae6ae9ee61cc3159d914892a1e23 Mon Sep 17 00:00:00 2001 From: Tobias <96661824+CrazyWolf13@users.noreply.github.com> Date: Thu, 3 Jul 2025 11:20:39 +0200 Subject: [PATCH 149/463] Update vikunja.sh --- ct/vikunja.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ct/vikunja.sh b/ct/vikunja.sh index 621a470b..0b547f03 100644 --- a/ct/vikunja.sh +++ b/ct/vikunja.sh @@ -27,17 +27,18 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi - + + msg_info "Selecting version" if whiptail --backtitle "Vikunja Update" --title "🔄 VERSION SELECTION" --yesno \ "Choose the version type to update to:\n\n• STABLE: Recommended for production use\n• UNSTABLE: Latest development version\n\n⚠️ WARNING: Unstable versions may contain bugs,\nbe incomplete, or cause system instability.\nOnly use for testing purposes.\n\nDo you want to use the UNSTABLE version?\n(No = Stable, Yes = Unstable)" 16 70 --defaultno then RELEASE="unstable" FILENAME="vikunja-${RELEASE}-x86_64.deb" - msg_info "Selected UNSTABLE version" + msg_ok "Selected UNSTABLE version" else RELEASE=$(curl -fsSL https://dl.vikunja.io/vikunja/ | grep -oP 'href="/vikunja/\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n 1) FILENAME="vikunja-${RELEASE}-amd64.deb" - msg_info "Selected STABLE version: ${RELEASE}" + msg_ok "Selected STABLE version: ${RELEASE}" fi if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then From eb1a41407f820e0ecb2a1740daf659581def01ff Mon Sep 17 00:00:00 2001 From: Tobias <96661824+CrazyWolf13@users.noreply.github.com> Date: Thu, 3 Jul 2025 11:33:00 +0200 Subject: [PATCH 150/463] Update vikunja.sh --- ct/vikunja.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/vikunja.sh b/ct/vikunja.sh index 0b547f03..38d014d8 100644 --- a/ct/vikunja.sh +++ b/ct/vikunja.sh @@ -28,14 +28,15 @@ function update_script() { exit fi - msg_info "Selecting version" if whiptail --backtitle "Vikunja Update" --title "🔄 VERSION SELECTION" --yesno \ "Choose the version type to update to:\n\n• STABLE: Recommended for production use\n• UNSTABLE: Latest development version\n\n⚠️ WARNING: Unstable versions may contain bugs,\nbe incomplete, or cause system instability.\nOnly use for testing purposes.\n\nDo you want to use the UNSTABLE version?\n(No = Stable, Yes = Unstable)" 16 70 --defaultno then + msg_info "Selecting version" RELEASE="unstable" FILENAME="vikunja-${RELEASE}-x86_64.deb" msg_ok "Selected UNSTABLE version" else + msg_info "Selecting version" RELEASE=$(curl -fsSL https://dl.vikunja.io/vikunja/ | grep -oP 'href="/vikunja/\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n 1) FILENAME="vikunja-${RELEASE}-amd64.deb" msg_ok "Selected STABLE version: ${RELEASE}" From e0ccdb42fc60e92a5b9c2054cd014c1ec4f82344 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 13:22:19 +0200 Subject: [PATCH 151/463] testing --- ct/trilium.sh | 86 ++++++++++++++++++++++++++++++++++++ ct/zigbee2mqtt.sh | 90 -------------------------------------- install/trilium-install.sh | 44 +++++++++++++++++++ 3 files changed, 130 insertions(+), 90 deletions(-) create mode 100644 ct/trilium.sh delete mode 100644 ct/zigbee2mqtt.sh create mode 100644 install/trilium-install.sh diff --git a/ct/trilium.sh b/ct/trilium.sh new file mode 100644 index 00000000..be477e71 --- /dev/null +++ b/ct/trilium.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/TriliumNext/Trilium + +APP="Trilium" +var_tags="${var_tags:-notes}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-512}" +var_disk="${var_disk:-2}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +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/trilium ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + RELEASE=$(curl -fsSL https://api.github.com/repos/TriliumNext/Trilium/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') + if [[ "${RELEASE}" != "$(cat ~/.Trilium 2>/dev/null)" ]] || [[ ! -f ~/.Trilium ]]; then + + if [[ -d /opt/trilium/db ]]; then + DB_PATH="/opt/trilium/db" + DB_RESTORE_PATH="/opt/trilium/db" + elif [[ -d /opt/trilium/assets/db ]]; then + DB_PATH="/opt/trilium/assets/db" + DB_RESTORE_PATH="/opt/trilium/assets/db" + else + msg_error "Database not found in either /opt/trilium/db or /opt/trilium/assets/db" + exit 1 + fi + + msg_info "Stopping ${APP}" + systemctl stop trilium + sleep 1 + msg_ok "Stopped ${APP}" + + msg_info "Backing up Database" + mkdir -p /opt/trilium_backup + cp -r "${DB_PATH}" /opt/trilium_backup/ + rm -rf /opt/trilium + msg_ok "Backed up Database" + + fetch_and_deploy_gh_release "Trilium" "TriliumNext/Trilium" "prebuild" "latest" "/opt/trilium" "TriliumNotes-Server-*-linux-x64.tar.xz" + + # Restore database + msg_info "Restoring Database" + mkdir -p "$(dirname "${DB_RESTORE_PATH}")" + cp -r /opt/trilium_backup/$(basename "${DB_PATH}") "${DB_RESTORE_PATH}" + msg_ok "Restored Database" + + msg_info "Cleaning up" + rm -rf /opt/trilium_backup + msg_ok "Cleaned" + + msg_info "Starting ${APP}" + systemctl start trilium + sleep 1 + msg_ok "Started ${APP}" + msg_ok "Updated Successfully" + else + msg_ok "No update required. ${APP} is already at ${RELEASE}" + 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}http://${IP}:8080${CL}" diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh deleted file mode 100644 index f087d75b..00000000 --- a/ct/zigbee2mqtt.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2025 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://www.zigbee2mqtt.io/ - -APP="Zigbee2MQTT" -var_tags="${var_tags:-smarthome;zigbee;mqtt}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-1024}" -var_disk="${var_disk:-4}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -var_unprivileged="${var_unprivileged:-0}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - header_info - check_container_storage - check_container_resources - if [[ ! -d /opt/zigbee2mqtt ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - - if [[ -f ~/.zigbee2mqtt ]]; then - CURRENT="$(cat ~/.zigbee2mqtt)" - elif [[ -f /opt/${APP}_version.txt ]]; then - CURRENT="$(cat /opt/${APP}_version.txt)" - rm -f /opt/${APP}_version.txt - else - CURRENT="" - fi - - RELEASE=$(curl -fsSL https://api.github.com/repos/Koenkk/zigbee2mqtt/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - if [[ "$RELEASE" != "$CURRENT" ]]; then - if ! command -v jq &>/dev/null; then - $STD apt-get update - $STD apt-get install -y jq - fi - NODE_VERSION=24 NODE_MODULE="pnpm@$(curl -fsSL https://raw.githubusercontent.com/Koenkk/zigbee2mqtt/master/package.json | jq -r '.packageManager | split("@")[1]')" setup_nodejs - - msg_info "Stopping Service" - systemctl stop zigbee2mqtt - msg_ok "Stopped Service" - - msg_info "Creating Backup" - rm -rf /opt/${APP}_backup*.tar.gz - mkdir -p /opt/z2m_backup - $STD tar -czf /opt/z2m_backup/${APP}_backup_$(date +%Y%m%d%H%M%S).tar.gz -C /opt zigbee2mqtt - mv /opt/zigbee2mqtt/data /opt/z2m_backup - msg_ok "Backup Created" - - fetch_and_deploy_gh_release "Zigbee2MQTT" "Koenkk/zigbee2mqtt" "tarball" "latest" "/opt/zigbee2mqtt" - - msg_info "Updating ${APP} to v${RELEASE}" - rm -rf /opt/zigbee2mqtt/data - mv /opt/z2m_backup/data /opt/zigbee2mqtt - cd /opt/zigbee2mqtt - $STD pnpm install --frozen-lockfile - $STD pnpm build - msg_ok "Updated Zigbee2MQTT" - - msg_info "Starting Service" - systemctl start zigbee2mqtt - msg_ok "Started Service" - - msg_info "Cleaning up" - rm -rf /opt/z2m_backup - msg_ok "Cleaned up" - echo "${RELEASE}" >/opt/${APP}_version.txt - else - msg_ok "No update required. ${APP} is already at v${RELEASE}." - 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}http://${IP}:9442${CL}" diff --git a/install/trilium-install.sh b/install/trilium-install.sh new file mode 100644 index 00000000..6547b1ce --- /dev/null +++ b/install/trilium-install.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/TriliumNext/Trilium + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +fetch_and_deploy_gh_release "Trilium" "TriliumNext/Trilium" "prebuild" "latest" "/opt/trilium" "TriliumNotes-Server-*-linux-x64.tar.xz" + +msg_info "Creating Service" +cat </etc/systemd/system/trilium.service +[Unit] +Description=Trilium Daemon +After=syslog.target network.target + +[Service] +User=root +Type=simple +ExecStart=/opt/trilium/trilium.sh +WorkingDirectory=/opt/trilium/ +TimeoutStopSec=20 +Restart=always + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable --now -q trilium +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From b5e68e5b38aae097f82492145481f778b6c43157 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Thu, 3 Jul 2025 11:22:50 +0000 Subject: [PATCH 152/463] Update .app files (#675) Co-authored-by: GitHub Actions --- ct/headers/trilium | 6 ++++++ ct/headers/zigbee2mqtt | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 ct/headers/trilium delete mode 100644 ct/headers/zigbee2mqtt diff --git a/ct/headers/trilium b/ct/headers/trilium new file mode 100644 index 00000000..6f02b768 --- /dev/null +++ b/ct/headers/trilium @@ -0,0 +1,6 @@ + ______ _ ___ + /_ __/____(_) (_)_ ______ ___ + / / / ___/ / / / / / / __ `__ \ + / / / / / / / / /_/ / / / / / / +/_/ /_/ /_/_/_/\__,_/_/ /_/ /_/ + diff --git a/ct/headers/zigbee2mqtt b/ct/headers/zigbee2mqtt deleted file mode 100644 index f6925a01..00000000 --- a/ct/headers/zigbee2mqtt +++ /dev/null @@ -1,6 +0,0 @@ - _____ _ __ ___ __ _______ ____________ -/__ / (_)___ _/ /_ ___ ___ |__ \ / |/ / __ \/_ __/_ __/ - / / / / __ `/ __ \/ _ \/ _ \__/ // /|_/ / / / / / / / / - / /__/ / /_/ / /_/ / __/ __/ __// / / / /_/ / / / / / -/____/_/\__, /_.___/\___/\___/____/_/ /_/\___\_\/_/ /_/ - /____/ From 33bd4ac0e91a867efaf97a1ed7fca2b4b94267d6 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 13:30:38 +0200 Subject: [PATCH 153/463] Update tools.func --- misc/tools.func | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/misc/tools.func b/misc/tools.func index f9d4e36d..3d30bb81 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -883,7 +883,10 @@ function fetch_and_deploy_gh_release() { local asset_url="" for u in $(echo "$json" | jq -r '.assets[].browser_download_url'); do - [[ "$u" =~ $pattern || "$u" == *"$pattern" ]] && asset_url="$u" && break + if [[ "$u" == $pattern ]]; then + asset_url="$u" + break + fi done [[ -z "$asset_url" ]] && { From 77323e618e859acdae99554d82486e268e7bf704 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 14:07:18 +0200 Subject: [PATCH 154/463] Update tools.func --- misc/tools.func | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 3d30bb81..fe2f1e5b 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -798,6 +798,7 @@ function fetch_and_deploy_gh_release() { msg_info "Setup $app ($version)" + ### Tarball Mode ### if [[ "$mode" == "tarball" || "$mode" == "source" ]]; then url=$(echo "$json" | jq -r '.tarball_url // empty') [[ -z "$url" ]] && url="https://github.com/$repo/archive/refs/tags/v$version.tar.gz" @@ -818,6 +819,7 @@ function fetch_and_deploy_gh_release() { cp -r "$unpack_dir"/* "$target/" shopt -u dotglob nullglob + ### Binary Mode ### elif [[ "$mode" == "binary" ]]; then local arch arch=$(dpkg --print-architecture 2>/dev/null || uname -m) @@ -873,6 +875,7 @@ function fetch_and_deploy_gh_release() { } } + ### Prebuild Mode ### elif [[ "$mode" == "prebuild" ]]; then local pattern="$6" [[ -z "$pattern" ]] && { @@ -883,10 +886,12 @@ function fetch_and_deploy_gh_release() { local asset_url="" for u in $(echo "$json" | jq -r '.assets[].browser_download_url'); do - if [[ "$u" == $pattern ]]; then + case "$u" in + $pattern) asset_url="$u" break - fi + ;; + esac done [[ -z "$asset_url" ]] && { @@ -916,6 +921,7 @@ function fetch_and_deploy_gh_release() { return 1 fi + ### Singlefile Mode ### elif [[ "$mode" == "singlefile" ]]; then local pattern="$6" [[ -z "$pattern" ]] && { @@ -926,7 +932,12 @@ function fetch_and_deploy_gh_release() { local asset_url="" for u in $(echo "$json" | jq -r '.assets[].browser_download_url'); do - [[ "$u" =~ $pattern || "$u" == *"$pattern" ]] && asset_url="$u" && break + case "$u" in + $pattern) + asset_url="$u" + break + ;; + esac done [[ -z "$asset_url" ]] && { From 0123cec2acf859d9822cbff49e46447660bc5da1 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 14:27:06 +0200 Subject: [PATCH 155/463] test --- ct/trilium.sh | 2 +- install/trilium-install.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/trilium.sh b/ct/trilium.sh index be477e71..d205bf1f 100644 --- a/ct/trilium.sh +++ b/ct/trilium.sh @@ -52,7 +52,7 @@ function update_script() { rm -rf /opt/trilium msg_ok "Backed up Database" - fetch_and_deploy_gh_release "Trilium" "TriliumNext/Trilium" "prebuild" "latest" "/opt/trilium" "TriliumNotes-Server-*-linux-x64.tar.xz" + fetch_and_deploy_gh_release "Trilium" "TriliumNext/Trilium" "prebuild" "latest" "/opt/trilium" "TriliumNotes-Server*linux-x64.tar.xz" # Restore database msg_info "Restoring Database" diff --git a/install/trilium-install.sh b/install/trilium-install.sh index 6547b1ce..ebcf1d44 100644 --- a/install/trilium-install.sh +++ b/install/trilium-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -fetch_and_deploy_gh_release "Trilium" "TriliumNext/Trilium" "prebuild" "latest" "/opt/trilium" "TriliumNotes-Server-*-linux-x64.tar.xz" +fetch_and_deploy_gh_release "Trilium" "TriliumNext/Trilium" "prebuild" "latest" "/opt/trilium" "TriliumNotes-Server*linux-x64.tar.xz" msg_info "Creating Service" cat </etc/systemd/system/trilium.service From 93ccfec9f8214c7bb114cb66703eb6df23ae4793 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 14:33:51 +0200 Subject: [PATCH 156/463] Update tools.func --- misc/tools.func | 3 +++ 1 file changed, 3 insertions(+) diff --git a/misc/tools.func b/misc/tools.func index fe2f1e5b..726c6a0b 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -893,6 +893,9 @@ function fetch_and_deploy_gh_release() { ;; esac done + echo "DEBUG: Matching assets for pattern: '$pattern'" >&2 + echo "DEBUG: All available assets:" >&2 + echo "$json" | jq -r '.assets[].browser_download_url' >&2 [[ -z "$asset_url" ]] && { msg_error "No asset matching '$pattern' found" From 381309a37e4a40613c0246feda3089c2339aea93 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Thu, 3 Jul 2025 12:39:27 +0000 Subject: [PATCH 157/463] Update versions.json (#676) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 68 +++++++++++++++++++----------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index ace9471b..a3904c19 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,24 @@ [ + { + "name": "Dolibarr/dolibarr", + "version": "18.0.7", + "date": "2025-07-03T08:57:21Z" + }, + { + "name": "fuma-nama/fumadocs", + "version": "fumadocs-openapi@9.0.17", + "date": "2025-07-03T06:57:48Z" + }, + { + "name": "mattermost/mattermost", + "version": "preview-v0.1", + "date": "2025-06-27T14:35:47Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2111", + "date": "2025-07-03T05:50:31Z" + }, { "name": "esphome/esphome", "version": "2025.6.3", @@ -46,8 +66,8 @@ }, { "name": "keycloak/keycloak", - "version": "26.2.5", - "date": "2025-05-28T06:49:43Z" + "version": "26.3.0", + "date": "2025-07-02T12:26:44Z" }, { "name": "ollama/ollama", @@ -64,11 +84,6 @@ "version": "2025.7.0", "date": "2025-07-02T16:23:42Z" }, - { - "name": "fuma-nama/fumadocs", - "version": "fumadocs-core@15.6.1", - "date": "2025-07-02T15:29:41Z" - }, { "name": "nzbgetcom/nzbget", "version": "v25.1", @@ -99,11 +114,6 @@ "version": "release-5.1.2", "date": "2025-07-02T06:13:16Z" }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2107", - "date": "2025-07-02T05:53:02Z" - }, { "name": "diced/zipline", "version": "v4.2.0", @@ -224,11 +234,6 @@ "version": "1.7.8", "date": "2025-06-30T09:00:54Z" }, - { - "name": "mattermost/mattermost", - "version": "preview-v0.1", - "date": "2025-06-27T14:35:47Z" - }, { "name": "typesense/typesense", "version": "v29.0", @@ -349,11 +354,6 @@ "version": "4.1.0-beta.2", "date": "2025-06-26T14:23:26Z" }, - { - "name": "Dolibarr/dolibarr", - "version": "18.0.7", - "date": "2025-06-26T09:16:33Z" - }, { "name": "gristlabs/grist-core", "version": "v1.6.1", @@ -416,8 +416,8 @@ }, { "name": "runtipi/runtipi", - "version": "nightly", - "date": "2025-06-23T19:10:33Z" + "version": "v4.2.1", + "date": "2025-06-03T20:04:28Z" }, { "name": "VictoriaMetrics/VictoriaMetrics", @@ -463,5 +463,25 @@ "name": "go-gitea/gitea", "version": "v1.24.2", "date": "2025-06-20T20:37:55Z" + }, + { + "name": "immich-app/immich", + "version": "v1.135.3", + "date": "2025-06-20T20:19:20Z" + }, + { + "name": "Sonarr/Sonarr", + "version": "v4.0.15.2941", + "date": "2025-06-20T17:20:54Z" + }, + { + "name": "benzino77/tasmocompiler", + "version": "v12.7.0", + "date": "2025-06-20T08:31:16Z" + }, + { + "name": "paperless-ngx/paperless-ngx", + "version": "v2.17.1", + "date": "2025-06-19T19:35:01Z" } ] From 081059c7ccdbd8666a8177fd1e428f603ad8ebc0 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 14:40:27 +0200 Subject: [PATCH 158/463] test --- ct/trilium.sh | 3 +-- install/trilium-install.sh | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/trilium.sh b/ct/trilium.sh index d205bf1f..0a31428d 100644 --- a/ct/trilium.sh +++ b/ct/trilium.sh @@ -52,9 +52,8 @@ function update_script() { rm -rf /opt/trilium msg_ok "Backed up Database" - fetch_and_deploy_gh_release "Trilium" "TriliumNext/Trilium" "prebuild" "latest" "/opt/trilium" "TriliumNotes-Server*linux-x64.tar.xz" + fetch_and_deploy_gh_release "Trilium" "TriliumNext/Trilium" "prebuild" "latest" "/opt/trilium" "TriliumNotes-Server-*linux-x64.tar.xz" - # Restore database msg_info "Restoring Database" mkdir -p "$(dirname "${DB_RESTORE_PATH}")" cp -r /opt/trilium_backup/$(basename "${DB_PATH}") "${DB_RESTORE_PATH}" diff --git a/install/trilium-install.sh b/install/trilium-install.sh index ebcf1d44..f5ddd078 100644 --- a/install/trilium-install.sh +++ b/install/trilium-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -fetch_and_deploy_gh_release "Trilium" "TriliumNext/Trilium" "prebuild" "latest" "/opt/trilium" "TriliumNotes-Server*linux-x64.tar.xz" +fetch_and_deploy_gh_release "Trilium" "TriliumNext/Trilium" "prebuild" "latest" "/opt/trilium" "TriliumNotes-Server-*linux-x64.tar.xz" msg_info "Creating Service" cat </etc/systemd/system/trilium.service From 1df2af36547dd2082cbbc24c48ce2d328e5e4e8f Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 14:48:32 +0200 Subject: [PATCH 159/463] pattern --- misc/tools.func | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/misc/tools.func b/misc/tools.func index 726c6a0b..bb44e5d1 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -878,6 +878,8 @@ function fetch_and_deploy_gh_release() { ### Prebuild Mode ### elif [[ "$mode" == "prebuild" ]]; then local pattern="$6" + pattern="${pattern%\"}" + pattern="${pattern#\"}" [[ -z "$pattern" ]] && { msg_error "Mode 'prebuild' requires 6th parameter (asset filename pattern)" rm -rf "$tmpdir" @@ -927,6 +929,8 @@ function fetch_and_deploy_gh_release() { ### Singlefile Mode ### elif [[ "$mode" == "singlefile" ]]; then local pattern="$6" + pattern="${pattern%\"}" + pattern="${pattern#\"}" [[ -z "$pattern" ]] && { msg_error "Mode 'singlefile' requires 6th parameter (asset filename pattern)" rm -rf "$tmpdir" From 1ca01c1b16cf1c0c3376c20a169fb3751a6ee0f6 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 14:58:45 +0200 Subject: [PATCH 160/463] Update tools.func --- misc/tools.func | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index bb44e5d1..ac328097 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -877,8 +877,7 @@ function fetch_and_deploy_gh_release() { ### Prebuild Mode ### elif [[ "$mode" == "prebuild" ]]; then - local pattern="$6" - pattern="${pattern%\"}" + local pattern="${6%\"}" pattern="${pattern#\"}" [[ -z "$pattern" ]] && { msg_error "Mode 'prebuild' requires 6th parameter (asset filename pattern)" @@ -888,12 +887,14 @@ function fetch_and_deploy_gh_release() { local asset_url="" for u in $(echo "$json" | jq -r '.assets[].browser_download_url'); do - case "$u" in + filename_candidate="${u##*/}" + case "$filename_candidate" in $pattern) asset_url="$u" break ;; esac + done echo "DEBUG: Matching assets for pattern: '$pattern'" >&2 echo "DEBUG: All available assets:" >&2 @@ -928,8 +929,7 @@ function fetch_and_deploy_gh_release() { ### Singlefile Mode ### elif [[ "$mode" == "singlefile" ]]; then - local pattern="$6" - pattern="${pattern%\"}" + local pattern="${6%\"}" pattern="${pattern#\"}" [[ -z "$pattern" ]] && { msg_error "Mode 'singlefile' requires 6th parameter (asset filename pattern)" @@ -939,7 +939,8 @@ function fetch_and_deploy_gh_release() { local asset_url="" for u in $(echo "$json" | jq -r '.assets[].browser_download_url'); do - case "$u" in + filename_candidate="${u##*/}" + case "$filename_candidate" in $pattern) asset_url="$u" break From 83353a772c586c6ff6c02d823170cf146290a254 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 15:04:27 +0200 Subject: [PATCH 161/463] Update tools.func --- misc/tools.func | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index ac328097..61dfb39c 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -919,8 +919,8 @@ function fetch_and_deploy_gh_release() { $STD apt-get install -y unzip fi $STD unzip "$tmpdir/$filename" -d "$target" - elif [[ "$filename" == *.tar.gz ]]; then - tar -xzf "$tmpdir/$filename" -C "$target" + elif [[ "$filename" == *.tar.* ]]; then + tar -xf "$tmpdir/$filename" -C "$target" else msg_error "Unsupported archive format: $filename" rm -rf "$tmpdir" From 360bb5a458ef437bcc39208288579c0fbaa66aee Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 15:04:36 +0200 Subject: [PATCH 162/463] Update tools.func --- misc/tools.func | 3 --- 1 file changed, 3 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 61dfb39c..7add0207 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -896,9 +896,6 @@ function fetch_and_deploy_gh_release() { esac done - echo "DEBUG: Matching assets for pattern: '$pattern'" >&2 - echo "DEBUG: All available assets:" >&2 - echo "$json" | jq -r '.assets[].browser_download_url' >&2 [[ -z "$asset_url" ]] && { msg_error "No asset matching '$pattern' found" From c2fd842fbca65a3932de67078165680d8fa45df0 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 15:11:45 +0200 Subject: [PATCH 163/463] tar globbing --- misc/tools.func | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/misc/tools.func b/misc/tools.func index 7add0207..f07a0433 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -917,7 +917,13 @@ function fetch_and_deploy_gh_release() { fi $STD unzip "$tmpdir/$filename" -d "$target" elif [[ "$filename" == *.tar.* ]]; then - tar -xf "$tmpdir/$filename" -C "$target" + tar -xf "$tmpdir/$filename" -C "$tmpdir" + local unpack_dir + unpack_dir=$(find "$tmpdir" -mindepth 1 -maxdepth 1 -type d | head -n1) + + shopt -s dotglob nullglob + cp -r "$unpack_dir"/* "$target/" + shopt -u dotglob nullglob else msg_error "Unsupported archive format: $filename" rm -rf "$tmpdir" From 4eee9f81879ad51df8177655f3f357630719c818 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 3 Jul 2025 15:13:34 +0200 Subject: [PATCH 164/463] Update tools.func --- misc/tools.func | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index f07a0433..1793ce45 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -917,13 +917,7 @@ function fetch_and_deploy_gh_release() { fi $STD unzip "$tmpdir/$filename" -d "$target" elif [[ "$filename" == *.tar.* ]]; then - tar -xf "$tmpdir/$filename" -C "$tmpdir" - local unpack_dir - unpack_dir=$(find "$tmpdir" -mindepth 1 -maxdepth 1 -type d | head -n1) - - shopt -s dotglob nullglob - cp -r "$unpack_dir"/* "$target/" - shopt -u dotglob nullglob + tar --strip-components=1 -xf "$tmpdir/$filename" -C "$target" else msg_error "Unsupported archive format: $filename" rm -rf "$tmpdir" From 406bc0bef3c1aa716aa4b90f979f281108047ea3 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Fri, 4 Jul 2025 01:39:27 +0000 Subject: [PATCH 165/463] Update versions.json (#679) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 116 ++++++++++++++--------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index a3904c19..b67df43b 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,59 @@ [ + { + "name": "hyperion-project/hyperion.ng", + "version": "2.1.1", + "date": "2025-06-14T17:45:06Z" + }, + { + "name": "steveiliop56/tinyauth", + "version": "v3.4.1", + "date": "2025-06-11T07:53:44Z" + }, + { + "name": "outline/outline", + "version": "v0.85.0", + "date": "2025-07-04T00:06:47Z" + }, + { + "name": "home-assistant/operating-system", + "version": "15.2", + "date": "2025-04-14T15:37:12Z" + }, + { + "name": "cloudflare/cloudflared", + "version": "2025.7.0", + "date": "2025-07-03T17:08:15Z" + }, + { + "name": "rabbitmq/rabbitmq-server", + "version": "v4.1.2", + "date": "2025-07-03T16:59:29Z" + }, + { + "name": "bunkerity/bunkerweb", + "version": "testing", + "date": "2025-07-03T16:52:55Z" + }, + { + "name": "Checkmk/checkmk", + "version": "v2.4.0p6", + "date": "2025-07-03T16:40:42Z" + }, + { + "name": "influxdata/influxdb", + "version": "v3.2.1", + "date": "2025-07-03T16:09:19Z" + }, + { + "name": "cockpit-project/cockpit", + "version": "310.5", + "date": "2025-07-03T14:05:25Z" + }, + { + "name": "n8n-io/n8n", + "version": "n8n@1.100.0", + "date": "2025-06-23T12:48:35Z" + }, { "name": "Dolibarr/dolibarr", "version": "18.0.7", @@ -124,11 +179,6 @@ "version": "v0.20.2", "date": "2025-07-02T00:37:07Z" }, - { - "name": "hyperion-project/hyperion.ng", - "version": "2.1.1", - "date": "2025-06-14T17:45:06Z" - }, { "name": "Threadfin/Threadfin", "version": "1.2.35", @@ -169,11 +219,6 @@ "version": "v1.30.0", "date": "2025-07-01T11:29:11Z" }, - { - "name": "Checkmk/checkmk", - "version": "v2.2.0p44-rc1", - "date": "2025-07-01T11:10:25Z" - }, { "name": "rcourtman/Pulse", "version": "v99.99.99", @@ -214,11 +259,6 @@ "version": "v2.53.5", "date": "2025-06-30T11:01:12Z" }, - { - "name": "n8n-io/n8n", - "version": "n8n@1.100.0", - "date": "2025-06-23T12:48:35Z" - }, { "name": "jupyter/notebook", "version": "v7.4.4", @@ -305,20 +345,15 @@ "date": "2025-06-27T09:53:57Z" }, { - "name": "cockpit-project/cockpit", - "version": "341.1", - "date": "2025-06-27T08:50:16Z" + "name": "fallenbagel/jellyseerr", + "version": "preview-seerr", + "date": "2025-06-27T06:10:03Z" }, { "name": "MediaBrowser/Emby.Releases", "version": "4.9.1.2", "date": "2025-06-26T22:08:00Z" }, - { - "name": "home-assistant/operating-system", - "version": "15.2", - "date": "2025-04-14T15:37:12Z" - }, { "name": "netbox-community/netbox", "version": "v4.3.3", @@ -364,21 +399,11 @@ "version": "v4.101.2", "date": "2025-06-25T21:18:52Z" }, - { - "name": "influxdata/influxdb", - "version": "v3.2.0", - "date": "2025-06-25T17:31:48Z" - }, { "name": "wavelog/wavelog", "version": "2.0.5", "date": "2025-06-25T14:53:31Z" }, - { - "name": "bunkerity/bunkerweb", - "version": "testing", - "date": "2025-06-16T18:10:42Z" - }, { "name": "moghtech/komodo", "version": "v1.18.4", @@ -404,11 +429,6 @@ "version": "v2.18.0", "date": "2025-06-24T08:29:55Z" }, - { - "name": "fallenbagel/jellyseerr", - "version": "preview-fix-proxy-axios", - "date": "2025-06-24T08:50:22Z" - }, { "name": "minio/minio", "version": "RELEASE.2025-06-13T11-33-47Z", @@ -463,25 +483,5 @@ "name": "go-gitea/gitea", "version": "v1.24.2", "date": "2025-06-20T20:37:55Z" - }, - { - "name": "immich-app/immich", - "version": "v1.135.3", - "date": "2025-06-20T20:19:20Z" - }, - { - "name": "Sonarr/Sonarr", - "version": "v4.0.15.2941", - "date": "2025-06-20T17:20:54Z" - }, - { - "name": "benzino77/tasmocompiler", - "version": "v12.7.0", - "date": "2025-06-20T08:31:16Z" - }, - { - "name": "paperless-ngx/paperless-ngx", - "version": "v2.17.1", - "date": "2025-06-19T19:35:01Z" } ] From 59a414cc60387bf6c24eeaa9a7255e03f01ece11 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 09:11:28 +0200 Subject: [PATCH 166/463] Update core.func --- misc/core.func | 102 +++++++++---------------------------------------- 1 file changed, 17 insertions(+), 85 deletions(-) diff --git a/misc/core.func b/misc/core.func index 6a14a886..62e33797 100644 --- a/misc/core.func +++ b/misc/core.func @@ -365,85 +365,6 @@ fatal() { kill -INT $$ } -# # Ensure POSIX compatibility across Alpine and Debian/Ubuntu -# # === Spinner Start === -# # Trap cleanup on various signals -# trap 'cleanup_spinner' EXIT INT TERM HUP - -# spinner_frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏') - -# # === Spinner Start === -# start_spinner() { -# local msg="$1" -# local spin_i=0 -# local interval=0.1 - -# stop_spinner -# SPINNER_MSG="$msg" -# SPINNER_ACTIVE=1 - -# { -# while [[ "$SPINNER_ACTIVE" -eq 1 ]]; do -# if [[ -t 2 ]]; then -# printf "\r\e[2K%s %b" "${TAB}${spinner_frames[spin_i]}${TAB}" "${YW}${SPINNER_MSG}${CL}" >&2 -# else -# printf "%s...\n" "$SPINNER_MSG" >&2 -# break -# fi -# spin_i=$(((spin_i + 1) % ${#spinner_frames[@]})) -# sleep "$interval" -# done -# } & - -# local pid=$! -# if ps -p "$pid" >/dev/null 2>&1; then -# SPINNER_PID="$pid" -# else -# SPINNER_ACTIVE=0 -# SPINNER_PID="" -# fi -# } - -# # === Spinner Stop === -# stop_spinner() { -# if [[ "$SPINNER_ACTIVE" -eq 1 && -n "$SPINNER_PID" ]]; then -# SPINNER_ACTIVE=0 - -# if kill -0 "$SPINNER_PID" 2>/dev/null; then -# kill "$SPINNER_PID" 2>/dev/null || true -# for _ in $(seq 1 10); do -# sleep 0.05 -# kill -0 "$SPINNER_PID" 2>/dev/null || break -# done -# fi - -# if [[ "$SPINNER_PID" =~ ^[0-9]+$ ]]; then -# ps -p "$SPINNER_PID" -o pid= >/dev/null 2>&1 && wait "$SPINNER_PID" 2>/dev/null || true -# fi - -# printf "\r\e[2K" >&2 -# SPINNER_PID="" -# fi -# } - -# cleanup_spinner() { -# stop_spinner -# } - -# msg_info() { -# local msg="$1" -# [[ -z "$msg" || -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return -# MSG_INFO_SHOWN["$msg"]=1 - -# stop_spinner -# echo -e "OS: ${var_os:-}" -# if [[ "${VERBOSE:-no}" != "no" || "${var_os:-}" == "alpine" || ! -t 2 ]]; then -# printf "\r\e[2K%s %b\n" "$HOURGLASS" "${YW}${msg}${CL}" >&2 -# else -# start_spinner "$msg" -# fi -# } - spinner() { local chars=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏) local i=0 @@ -474,12 +395,23 @@ stop_spinner() { msg_info() { local msg="$1" - SPINNER_MSG="$msg" - color_spinner - spinner & - SPINNER_PID=$! - echo "$SPINNER_PID" >/tmp/.spinner.pid - disown "$SPINNER_PID" 2>/dev/null || true + [[ -z "$msg" || -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return + MSG_INFO_SHOWN["$msg"]=1 + + stop_spinner + + local HOURGLASS="${TAB}⏳${TAB}" + + if [[ "${VERBOSE:-no}" != "no" || "${var_os:-}" == "alpine" || ! -t 2 ]]; then + printf "\r\e[2K%s %b\n" "$HOURGLASS" "${YW}${msg}${CL}" >&2 + else + SPINNER_MSG="$msg" + color_spinner + spinner & + SPINNER_PID=$! + echo "$SPINNER_PID" >/tmp/.spinner.pid + disown "$SPINNER_PID" 2>/dev/null || true + fi } msg_ok() { From 5cd9b2e4845e3ba8d43b7db8bfcc0a4dba2b25c4 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 09:11:40 +0200 Subject: [PATCH 167/463] Update core.func --- misc/core.func | 2 -- 1 file changed, 2 deletions(-) diff --git a/misc/core.func b/misc/core.func index 62e33797..63d17a07 100644 --- a/misc/core.func +++ b/misc/core.func @@ -400,8 +400,6 @@ msg_info() { stop_spinner - local HOURGLASS="${TAB}⏳${TAB}" - if [[ "${VERBOSE:-no}" != "no" || "${var_os:-}" == "alpine" || ! -t 2 ]]; then printf "\r\e[2K%s %b\n" "$HOURGLASS" "${YW}${msg}${CL}" >&2 else From cea9ebec37dc88b54806d15fa1c5d75797128ec5 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 09:17:33 +0200 Subject: [PATCH 168/463] Update core.func --- misc/core.func | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/core.func b/misc/core.func index 63d17a07..62e33797 100644 --- a/misc/core.func +++ b/misc/core.func @@ -400,6 +400,8 @@ msg_info() { stop_spinner + local HOURGLASS="${TAB}⏳${TAB}" + if [[ "${VERBOSE:-no}" != "no" || "${var_os:-}" == "alpine" || ! -t 2 ]]; then printf "\r\e[2K%s %b\n" "$HOURGLASS" "${YW}${msg}${CL}" >&2 else From e2865f9e6abd60585052cb0c73f95fca171c86f1 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 09:20:33 +0200 Subject: [PATCH 169/463] Update core.func --- misc/core.func | 106 ++++++++++--------------------------------------- 1 file changed, 20 insertions(+), 86 deletions(-) diff --git a/misc/core.func b/misc/core.func index 62e33797..1632b1bd 100644 --- a/misc/core.func +++ b/misc/core.func @@ -250,79 +250,6 @@ header_info() { fi } -# ------------------------------------------------------------------------------ -# Performs a curl request with retry logic and inline feedback. -# ------------------------------------------------------------------------------ - -run_curl() { - if [ "$VERBOSE" = "no" ]; then - $STD curl "$@" - else - curl "$@" - fi -} - -curl_handler() { - set +e - trap 'set -e' RETURN - local args=() - local url="" - local max_retries=3 - local delay=2 - local attempt=1 - local exit_code - local has_output_file=false - local result="" - - # Parse arguments - for arg in "$@"; do - if [[ "$arg" != -* && -z "$url" ]]; then - url="$arg" - fi - [[ "$arg" == "-o" || "$arg" == --output ]] && has_output_file=true - args+=("$arg") - done - - if [[ -z "$url" ]]; then - msg_error "No valid URL or option entered for curl_handler" - return 1 - fi - - $STD msg_info "Fetching: $url" - - while [[ $attempt -le $max_retries ]]; do - if $has_output_file; then - $STD run_curl "${args[@]}" - exit_code=$? - else - result=$(run_curl "${args[@]}") - exit_code=$? - fi - - if [[ $exit_code -eq 0 ]]; then - $STD msg_ok "Fetched: $url" - $has_output_file || printf '%s' "$result" - return 0 - fi - - if ((attempt >= max_retries)); then - # Read error log if it exists - if [ -s /tmp/curl_error.log ]; then - local curl_stderr - curl_stderr=$(&2 - sleep "$delay" - ((attempt++)) - done - set -e -} - # ------------------------------------------------------------------------------ # Handles specific curl error codes and displays descriptive messages. # ------------------------------------------------------------------------------ @@ -386,32 +313,39 @@ stop_spinner() { wait "$pid" 2>/dev/null || true fi rm -f /tmp/.spinner.pid - unset SPINNER_PID fi - stty sane 2>/dev/null - #printf "\r\033[K\e[?25h\n" + unset SPINNER_PID SPINNER_MSG + stty sane 2>/dev/null || true } msg_info() { local msg="$1" - [[ -z "$msg" || -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return + [[ -z "$msg" ]] && return + + if ! declare -p MSG_INFO_SHOWN &>/dev/null || ! declare -A MSG_INFO_SHOWN &>/dev/null; then + declare -gA MSG_INFO_SHOWN=() + fi + + if [[ -n "${MSG_INFO_SHOWN["$msg"]+x}" ]]; then + return + fi MSG_INFO_SHOWN["$msg"]=1 stop_spinner - local HOURGLASS="${TAB}⏳${TAB}" - if [[ "${VERBOSE:-no}" != "no" || "${var_os:-}" == "alpine" || ! -t 2 ]]; then + local HOURGLASS="${TAB}⏳${TAB}" printf "\r\e[2K%s %b\n" "$HOURGLASS" "${YW}${msg}${CL}" >&2 - else - SPINNER_MSG="$msg" - color_spinner - spinner & - SPINNER_PID=$! - echo "$SPINNER_PID" >/tmp/.spinner.pid - disown "$SPINNER_PID" 2>/dev/null || true + return fi + + SPINNER_MSG="$msg" + color_spinner + spinner & + SPINNER_PID=$! + echo "$SPINNER_PID" >/tmp/.spinner.pid + disown "$SPINNER_PID" 2>/dev/null || true } msg_ok() { From 1f4ea27a0bf1086f2abbb22961e8c58d2cff1e6c Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 09:32:42 +0200 Subject: [PATCH 170/463] Update core.func --- misc/core.func | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/misc/core.func b/misc/core.func index 1632b1bd..11914ebe 100644 --- a/misc/core.func +++ b/misc/core.func @@ -351,7 +351,18 @@ msg_info() { msg_ok() { stop_spinner local msg="$1" - echo -e "${BFR:-} ${CM:-✔️} ${GN}${msg}${CL}" + if [[ "${VERBOSE:-no}" != "no" || "${var_os:-}" == "alpine" || ! -t 2 ]]; then + local CHECK="${TAB}✔️${TAB}" + local PREV="${SPINNER_MSG:-}" + + if [[ -n "$PREV" && "$msg" == "$PREV" ]]; then + printf "\r\e[2K%s %b\n" "$CHECK" "${GN}${msg}${CL}" >&2 + else + printf "%s %b\n" "$CHECK" "${GN}${msg}${CL}" >&2 + fi + else + echo -e "${BFR:-} ${CM:-✔️} ${GN}${msg}${CL}" + fi } msg_error() { From d64b34695c448ceed54c5ba052c145112a513710 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 09:37:50 +0200 Subject: [PATCH 171/463] Update core.func --- misc/core.func | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/misc/core.func b/misc/core.func index 11914ebe..a87f3c05 100644 --- a/misc/core.func +++ b/misc/core.func @@ -326,21 +326,19 @@ msg_info() { if ! declare -p MSG_INFO_SHOWN &>/dev/null || ! declare -A MSG_INFO_SHOWN &>/dev/null; then declare -gA MSG_INFO_SHOWN=() fi - - if [[ -n "${MSG_INFO_SHOWN["$msg"]+x}" ]]; then - return - fi + [[ -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return MSG_INFO_SHOWN["$msg"]=1 stop_spinner + SPINNER_MSG="$msg" + if [[ "${VERBOSE:-no}" != "no" || "${var_os:-}" == "alpine" || ! -t 2 ]]; then local HOURGLASS="${TAB}⏳${TAB}" - printf "\r\e[2K%s %b\n" "$HOURGLASS" "${YW}${msg}${CL}" >&2 + printf "\r\e[2K%s %b" "$HOURGLASS" "${YW}${msg}${CL}" >&2 return fi - SPINNER_MSG="$msg" color_spinner spinner & SPINNER_PID=$! From fd5bf89d05236daa77576f56e25200f3b16bbeea Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 10:17:20 +0200 Subject: [PATCH 172/463] timezone issue --- misc/build.func | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/misc/build.func b/misc/build.func index 0c6210f9..282123b0 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1248,31 +1248,38 @@ EOF if ([ "$CT_TYPE" == "0" ] || [ "$is_vaapi_app" == "true" ]) && ([[ -e /dev/dri/renderD128 ]] || [[ -e /dev/dri/card0 ]] || [[ -e /dev/fb0 ]]); then - msg_custom "⚙️" "\e[36m" "VAAPI passthrough configuration for LXC container" + msg_custom "⚙️" "\e[36m" "Configuring VAAPI passthrough for LXC container" if [ "$CT_TYPE" != "0" ]; then - msg_custom "⚠️" "\e[33m" "Container is unprivileged – VAAPI passthrough may not work depending on host configuration." + msg_custom "⚠️" "\e[33m" "Container is unprivileged – VAAPI passthrough may not work without additional host configuration (e.g., idmap)." + fi + + msg_custom "ℹ️" "\e[36m" "VAAPI enables GPU hardware acceleration (e.g., for video transcoding in Jellyfin or Plex)." + msg_custom "📦" "\e[36m" "The following GPU-related devices were detected on the host and can be mounted into the container." + + VAAPI_ALL=no + read -rp " ➤ Automatically mount all VAAPI devices? [Y/n]: " VAAPI_ALL + + if [[ ! "$VAAPI_ALL" =~ ^[Nn]$ ]]; then + VAAPI_ALL=yes fi if [[ -e /dev/dri/renderD128 ]]; then - read -rp " ➤ /dev/dri/renderD128 found – mount into container? [y/N]: " MOUNT_D128 - if [[ "$MOUNT_D128" =~ ^[Yy]$ ]]; then + if [[ "$VAAPI_ALL" == "yes" ]] || read -rp " ➤ /dev/dri/renderD128 (GPU rendering) – mount? [Y/n]: " yn && [[ "$yn" =~ ^[Yy]$|^$ ]]; then echo "lxc.cgroup2.devices.allow: c 226:128 rwm" >>"$LXC_CONFIG" echo "lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file" >>"$LXC_CONFIG" fi fi if [[ -e /dev/dri/card0 ]]; then - read -rp " ➤ /dev/dri/card0 found – mount into container? [y/N]: " MOUNT_CARD0 - if [[ "$MOUNT_CARD0" =~ ^[Yy]$ ]]; then + if [[ "$VAAPI_ALL" == "yes" ]] || read -rp " ➤ /dev/dri/card0 (GPU interface) – mount? [Y/n]: " yn && [[ "$yn" =~ ^[Yy]$|^$ ]]; then echo "lxc.cgroup2.devices.allow: c 226:0 rwm" >>"$LXC_CONFIG" echo "lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file" >>"$LXC_CONFIG" fi fi if [[ -e /dev/fb0 ]]; then - read -rp " ➤ /dev/fb0 (framebuffer) found – mount as well? [y/N]: " MOUNT_FB0 - if [[ "$MOUNT_FB0" =~ ^[Yy]$ ]]; then + if [[ "$VAAPI_ALL" == "yes" ]] || read -rp " ➤ /dev/fb0 (framebuffer) – mount as well? [Y/n]: " yn && [[ "$yn" =~ ^[Yy]$|^$ ]]; then echo "lxc.cgroup2.devices.allow: c 29:0 rwm" >>"$LXC_CONFIG" echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >>"$LXC_CONFIG" fi @@ -1295,6 +1302,7 @@ EOF msg_info "Starting LXC Container" pct start "$CTID" msg_ok "Started LXC Container" + msg_info "Customizing LXC Container" if [ "$var_os" == "alpine" ]; then sleep 3 @@ -1312,10 +1320,14 @@ EOF' locale-gen >/dev/null && \ export LANG=\$locale_line" + if [[ -z "${tz:-}" ]]; then + tz=$(timedatectl show --property=Timezone --value 2>/dev/null || echo "Etc/UTC") + fi + if pct exec "$CTID" -- test -e "/usr/share/zoneinfo/$tz"; then - pct exec "$CTID" -- bash -c "echo $tz >/etc/timezone && ln -sf /usr/share/zoneinfo/$tz /etc/localtime" + pct exec "$CTID" -- bash -c "tz='$tz'; echo \"\$tz\" >/etc/timezone && ln -sf \"/usr/share/zoneinfo/\$tz\" /etc/localtime" else - msg_info "Skipping timezone setup – zone '$tz' not found in container" + msg_warn "Skipping timezone setup – zone '$tz' not found in container" fi pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" From 9747828a9e30456ad0bfe882206e356ca6481b06 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 10:18:42 +0200 Subject: [PATCH 173/463] Update core.func --- misc/core.func | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/core.func b/misc/core.func index a87f3c05..79c90eb1 100644 --- a/misc/core.func +++ b/misc/core.func @@ -330,7 +330,6 @@ msg_info() { MSG_INFO_SHOWN["$msg"]=1 stop_spinner - SPINNER_MSG="$msg" if [[ "${VERBOSE:-no}" != "no" || "${var_os:-}" == "alpine" || ! -t 2 ]]; then From 3db4479cd0b5637db70c89af5ee23ef9e84c4c0b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 10:18:54 +0200 Subject: [PATCH 174/463] Update core.func --- misc/core.func | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/misc/core.func b/misc/core.func index 79c90eb1..b1dda6d3 100644 --- a/misc/core.func +++ b/misc/core.func @@ -350,13 +350,7 @@ msg_ok() { local msg="$1" if [[ "${VERBOSE:-no}" != "no" || "${var_os:-}" == "alpine" || ! -t 2 ]]; then local CHECK="${TAB}✔️${TAB}" - local PREV="${SPINNER_MSG:-}" - - if [[ -n "$PREV" && "$msg" == "$PREV" ]]; then - printf "\r\e[2K%s %b\n" "$CHECK" "${GN}${msg}${CL}" >&2 - else - printf "%s %b\n" "$CHECK" "${GN}${msg}${CL}" >&2 - fi + printf "\r\e[2K%s %b\n" "$CHECK" "${GN}${msg}${CL}" >&2 else echo -e "${BFR:-} ${CM:-✔️} ${GN}${msg}${CL}" fi From a9fabb94426d8cf47a4481682eec5a9b72b549f7 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 11:05:21 +0200 Subject: [PATCH 175/463] some alpine to test --- ct/alpine-komodo.sh | 58 +++++++++++++++++++ ct/alpine-tinyauth.sh | 58 +++++++++++++++++++ install/alpine-komodo-install.sh | 79 ++++++++++++++++++++++++++ install/alpine-tinyauth-install.sh | 90 ++++++++++++++++++++++++++++++ misc/build.func | 65 +++++++++++++-------- 5 files changed, 327 insertions(+), 23 deletions(-) create mode 100644 ct/alpine-komodo.sh create mode 100644 ct/alpine-tinyauth.sh create mode 100644 install/alpine-komodo-install.sh create mode 100644 install/alpine-tinyauth-install.sh diff --git a/ct/alpine-komodo.sh b/ct/alpine-komodo.sh new file mode 100644 index 00000000..f7ef40a4 --- /dev/null +++ b/ct/alpine-komodo.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://komo.do + +APP="Alpine-Komodo" +var_tags="${var_tags:-docker,alpine}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-1024}" +var_disk="${var_disk:-10}" +var_os="${var_os:-alpine}" +var_version="${var_version:-3.22}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + [[ -d /opt/komodo ]] || { + msg_error "No ${APP} Installation Found!" + exit 1 + } + + msg_info "Updating ${APP}" + COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1) + if [[ -z "$COMPOSE_FILE" ]]; then + msg_error "No valid compose file found in /opt/komodo!" + exit 1 + fi + COMPOSE_BASENAME=$(basename "$COMPOSE_FILE") + BACKUP_FILE="/opt/komodo/${COMPOSE_BASENAME}.bak_$(date +%Y%m%d_%H%M%S)" + cp "$COMPOSE_FILE" "$BACKUP_FILE" || { + msg_error "Failed to create backup of ${COMPOSE_BASENAME}!" + exit 1 + } + GITHUB_URL="https://raw.githubusercontent.com/moghtech/komodo/main/compose/${COMPOSE_BASENAME}" + if ! curl -fsSL "$GITHUB_URL" -o "$COMPOSE_FILE"; then + msg_error "Failed to download ${COMPOSE_BASENAME} from GitHub!" + mv "$BACKUP_FILE" "$COMPOSE_FILE" + exit 1 + fi + $STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d + msg_ok "Updated ${APP}" + 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}:9120${CL}" diff --git a/ct/alpine-tinyauth.sh b/ct/alpine-tinyauth.sh new file mode 100644 index 00000000..bab0004b --- /dev/null +++ b/ct/alpine-tinyauth.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: Slaviša Arežina (tremor021) | Co-Author: Stavros (steveiliop56) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/steveiliop56/tinyauth + +APP="Alpine-Tinyauth" +var_tags="${var_tags:-alpine;auth}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-256}" +var_disk="${var_disk:-2}" +var_os="${var_os:-alpine}" +var_version="${var_version:-3.22}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + if [[ ! -d /opt/tinyauth ]]; then + msg_error "No ${APP} Installation Found!" + exit 1 + fi + + msg_info "Updating packages" + $STD apk -U upgrade + msg_ok "Updated packages" + + msg_info "Updating Tinyauth" + RELEASE=$(curl -s https://api.github.com/repos/steveiliop56/tinyauth/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') + + if [ "${RELEASE}" != "$(cat /opt/tinyauth_version.txt)" ] || [ ! -f /opt/tinyauth_version.txt ]; then + $STD service tinyauth stop + rm -f /opt/tinyauth/tinyauth + curl -fsSL "https://github.com/steveiliop56/tinyauth/releases/download/v${RELEASE}/tinyauth-amd64" -o /opt/tinyauth/tinyauth + chmod +x /opt/tinyauth/tinyauth + echo "${RELEASE}" >/opt/tinyauth_version.txt + msg_info "Restarting Tinyauth" + $STD service tinyauth start + msg_ok "Restarted Tinyauth" + msg_ok "Updated Tinyauth" + else + msg_ok "No update required. ${APP} is already at ${RELEASE}" + fi + exit 0 +} + +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}:3000${CL}" diff --git a/install/alpine-komodo-install.sh b/install/alpine-komodo-install.sh new file mode 100644 index 00000000..e87bf687 --- /dev/null +++ b/install/alpine-komodo-install.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://komo.do/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apk add --no-cache ca-certificates openssl +msg_ok "Installed Dependencies" + +msg_info "Setup Docker Repository" +$STD apk add --no-cache docker docker-cli docker-compose openrc +msg_ok "Setup Docker Repository" + +msg_info "Enabling Docker Service" +$STD rc-update add docker boot +$STD service docker start +msg_ok "Enabled Docker Service" + +echo "${TAB3}Choose the database for Komodo installation:" +echo "${TAB3}1) MongoDB (recommended)" +echo "${TAB3}2) SQLite" +echo "${TAB3}3) PostgreSQL" +read -rp "${TAB3}Enter your choice (default: 1): " DB_CHOICE +DB_CHOICE=${DB_CHOICE:-1} + +case $DB_CHOICE in +1) + DB_COMPOSE_FILE="mongo.compose.yaml" + ;; +2) + DB_COMPOSE_FILE="sqlite.compose.yaml" + ;; +3) + DB_COMPOSE_FILE="postgres.compose.yaml" + ;; +*) + echo "Invalid choice. Defaulting to MongoDB." + DB_COMPOSE_FILE="mongo.compose.yaml" + ;; +esac + +mkdir -p /opt/komodo +cd /opt/komodo +curl -fsSL "https://raw.githubusercontent.com/moghtech/komodo/main/compose/$DB_COMPOSE_FILE" -o "$(basename "$DB_COMPOSE_FILE")" + +msg_info "Setup Komodo Environment" +curl -fsSL "https://raw.githubusercontent.com/moghtech/komodo/main/compose/compose.env" -o "/opt/komodo/compose.env" +DB_PASSWORD=$(openssl rand -base64 16 | tr -d '/+=') +PASSKEY=$(openssl rand -base64 24 | tr -d '/+=') +WEBHOOK_SECRET=$(openssl rand -base64 24 | tr -d '/+=') +JWT_SECRET=$(openssl rand -base64 24 | tr -d '/+=') + +sed -i "s/^KOMODO_DB_USERNAME=.*/KOMODO_DB_USERNAME=komodo_admin/" /opt/komodo/compose.env +sed -i "s/^KOMODO_DB_PASSWORD=.*/KOMODO_DB_PASSWORD=${DB_PASSWORD}/" /opt/komodo/compose.env +sed -i "s/^KOMODO_PASSKEY=.*/KOMODO_PASSKEY=${PASSKEY}/" /opt/komodo/compose.env +sed -i "s/^KOMODO_WEBHOOK_SECRET=.*/KOMODO_WEBHOOK_SECRET=${WEBHOOK_SECRET}/" /opt/komodo/compose.env +sed -i "s/^KOMODO_JWT_SECRET=.*/KOMODO_JWT_SECRET=${JWT_SECRET}/" /opt/komodo/compose.env +msg_ok "Setup Komodo Environment" + +msg_info "Initialize Komodo" +$STD docker compose -p komodo -f "/opt/komodo/$DB_COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d +msg_ok "Initialized Komodo" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apk cache clean +msg_ok "Cleaned" diff --git a/install/alpine-tinyauth-install.sh b/install/alpine-tinyauth-install.sh new file mode 100644 index 00000000..9aea59a6 --- /dev/null +++ b/install/alpine-tinyauth-install.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: Slaviša Arežina (tremor021) | Co-Author: Stavros (steveiliop56) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/steveiliop56/tinyauth + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apk add --no-cache curl openssl apache2-utils +msg_ok "Installed Dependencies" + +msg_info "Installing Tinyauth" +mkdir -p /opt/tinyauth + +RELEASE=$(curl -s https://api.github.com/repos/steveiliop56/tinyauth/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +curl -fsSL "https://github.com/steveiliop56/tinyauth/releases/download/v${RELEASE}/tinyauth-amd64" -o /opt/tinyauth/tinyauth +chmod +x /opt/tinyauth/tinyauth + +PASSWORD=$(openssl rand -base64 8 | tr -dc 'a-zA-Z0-9' | head -c 8) +USER=$(htpasswd -Bbn "tinyauth" "${PASSWORD}") + +cat < /opt/tinyauth/credentials.txt +Tinyauth Credentials +Username: tinyauth +Password: ${PASSWORD} +EOF + +echo "${RELEASE}" >/opt/tinyauth_version.txt +msg_ok "Installed Tinyauth" + +read -p "${TAB3}Enter your Tinyauth subdomain (e.g. https://tinyauth.example.com): " app_url + +msg_info "Creating Tinyauth Service" +SECRET=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 32) + +cat </opt/tinyauth/.env +SECRET=${SECRET} +USERS=${USER} +APP_URL=${app_url} +EOF + +sed -i -e 's/\$/\$\$/g' /opt/tinyauth/.env + +cat <<'EOF' >/etc/init.d/tinyauth +#!/sbin/openrc-run +description="Tinyauth Service" + +command="/opt/tinyauth/tinyauth" +directory="/opt/tinyauth" +command_user="root" +command_background="true" +pidfile="/var/run/tinyauth.pid" + +start_pre() { + if [ -f "/opt/tinyauth/.env" ]; then + while IFS= read -r line || [ -n "$line" ]; do + [ -z "$line" ] && continue + case "$line" in + '#'*) + continue + ;; + esac + export "$line" + done < "/opt/tinyauth/.env" + fi +} + +depend() { + use net +} +EOF + +chmod +x /etc/init.d/tinyauth +$STD rc-update add tinyauth default +msg_ok "Enabled Tinyauth Service" + +msg_info "Starting Tinyauth" +$STD service tinyauth start +msg_ok "Started Tinyauth" + +motd_ssh +customize diff --git a/misc/build.func b/misc/build.func index 282123b0..94fc86a2 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1248,45 +1248,64 @@ EOF if ([ "$CT_TYPE" == "0" ] || [ "$is_vaapi_app" == "true" ]) && ([[ -e /dev/dri/renderD128 ]] || [[ -e /dev/dri/card0 ]] || [[ -e /dev/fb0 ]]); then - msg_custom "⚙️" "\e[36m" "Configuring VAAPI passthrough for LXC container" + echo "" + msg_custom "⚙️ " "\e[96m" "Configuring VAAPI passthrough for LXC container" if [ "$CT_TYPE" != "0" ]; then - msg_custom "⚠️" "\e[33m" "Container is unprivileged – VAAPI passthrough may not work without additional host configuration (e.g., idmap)." + msg_custom "⚠️ " "\e[33m" "Container is unprivileged – VAAPI passthrough may not work without additional host configuration (e.g., idmap)." fi - msg_custom "ℹ️" "\e[36m" "VAAPI enables GPU hardware acceleration (e.g., for video transcoding in Jellyfin or Plex)." - msg_custom "📦" "\e[36m" "The following GPU-related devices were detected on the host and can be mounted into the container." + msg_custom "ℹ️ " "\e[96m" "VAAPI enables GPU hardware acceleration (e.g., for video transcoding in Jellyfin or Plex)." - VAAPI_ALL=no - read -rp " ➤ Automatically mount all VAAPI devices? [Y/n]: " VAAPI_ALL + echo "" + read -rp "➤ Automatically mount all available VAAPI devices? [Y/n]: " VAAPI_ALL - if [[ ! "$VAAPI_ALL" =~ ^[Nn]$ ]]; then - VAAPI_ALL=yes - fi - - if [[ -e /dev/dri/renderD128 ]]; then - if [[ "$VAAPI_ALL" == "yes" ]] || read -rp " ➤ /dev/dri/renderD128 (GPU rendering) – mount? [Y/n]: " yn && [[ "$yn" =~ ^[Yy]$|^$ ]]; then + if [[ "$VAAPI_ALL" =~ ^[Yy]$|^$ ]]; then + # Mount all devices automatically + if [[ -e /dev/dri/renderD128 ]]; then echo "lxc.cgroup2.devices.allow: c 226:128 rwm" >>"$LXC_CONFIG" echo "lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file" >>"$LXC_CONFIG" fi - fi - - if [[ -e /dev/dri/card0 ]]; then - if [[ "$VAAPI_ALL" == "yes" ]] || read -rp " ➤ /dev/dri/card0 (GPU interface) – mount? [Y/n]: " yn && [[ "$yn" =~ ^[Yy]$|^$ ]]; then + if [[ -e /dev/dri/card0 ]]; then echo "lxc.cgroup2.devices.allow: c 226:0 rwm" >>"$LXC_CONFIG" echo "lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file" >>"$LXC_CONFIG" fi - fi - - if [[ -e /dev/fb0 ]]; then - if [[ "$VAAPI_ALL" == "yes" ]] || read -rp " ➤ /dev/fb0 (framebuffer) – mount as well? [Y/n]: " yn && [[ "$yn" =~ ^[Yy]$|^$ ]]; then + if [[ -e /dev/fb0 ]]; then echo "lxc.cgroup2.devices.allow: c 29:0 rwm" >>"$LXC_CONFIG" echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >>"$LXC_CONFIG" fi - fi + if [[ -d /dev/dri ]]; then + echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG" + fi + else + # Manual selection per device + if [[ -e /dev/dri/renderD128 ]]; then + read -rp "➤ Mount /dev/dri/renderD128 (GPU rendering)? [y/N]: " MOUNT_D128 + if [[ "$MOUNT_D128" =~ ^[Yy]$ ]]; then + echo "lxc.cgroup2.devices.allow: c 226:128 rwm" >>"$LXC_CONFIG" + echo "lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file" >>"$LXC_CONFIG" + fi + fi - if [[ -d /dev/dri ]]; then - echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG" + if [[ -e /dev/dri/card0 ]]; then + read -rp "➤ Mount /dev/dri/card0 (GPU hardware interface)? [y/N]: " MOUNT_CARD0 + if [[ "$MOUNT_CARD0" =~ ^[Yy]$ ]]; then + echo "lxc.cgroup2.devices.allow: c 226:0 rwm" >>"$LXC_CONFIG" + echo "lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file" >>"$LXC_CONFIG" + fi + fi + + if [[ -e /dev/fb0 ]]; then + read -rp "➤ Mount /dev/fb0 (Framebuffer, GUI)? [y/N]: " MOUNT_FB0 + if [[ "$MOUNT_FB0" =~ ^[Yy]$ ]]; then + echo "lxc.cgroup2.devices.allow: c 29:0 rwm" >>"$LXC_CONFIG" + echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >>"$LXC_CONFIG" + fi + fi + + if [[ -d /dev/dri ]]; then + echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG" + fi fi fi From 2e11149f33ed6205cf95ab6087bbf4f561f68231 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 11:07:18 +0200 Subject: [PATCH 176/463] Update build copy.func --- misc/backup_07052025/build copy.func | 2110 ++++++++++++-------------- 1 file changed, 1011 insertions(+), 1099 deletions(-) diff --git a/misc/backup_07052025/build copy.func b/misc/backup_07052025/build copy.func index bec59ed4..bf5af2c4 100644 --- a/misc/backup_07052025/build copy.func +++ b/misc/backup_07052025/build copy.func @@ -5,13 +5,13 @@ # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE variables() { - NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. - var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. - INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. - PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase - DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call. - METHOD="default" # sets the METHOD variable to "default", used for the API call. - RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable. + NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. + var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. + INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. + PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase + DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call. + METHOD="default" # sets the METHOD variable to "default", used for the API call. + RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable. } source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) @@ -65,682 +65,594 @@ color # This function enables error handling in the script by setting options and defining a trap for the ERR signal. catch_errors() { - set -Eeuo pipefail - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + set -Eeuo pipefail + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { - source /dev/stdin <<<$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) - if [ -n "$SPINNER_PID" ] && ps -p "$SPINNER_PID" >/dev/null; then kill "$SPINNER_PID" >/dev/null; fi - printf "\e[?25h" - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - post_update_to_api "failed" "${command}" - echo -e "\n$error_message\n" + source /dev/stdin <<<$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) + if [ -n "$SPINNER_PID" ] && ps -p "$SPINNER_PID" >/dev/null; then kill "$SPINNER_PID" >/dev/null; fi + printf "\e[?25h" + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + post_update_to_api "failed" "${command}" + echo -e "\n$error_message\n" } -# # This function displays an informational message with logging support. -# declare -A MSG_INFO_SHOWN -# SPINNER_ACTIVE=0 -# SPINNER_PID="" -# SPINNER_MSG="" - -# trap 'stop_spinner' EXIT INT TERM HUP - -# start_spinner() { -# local msg="$1" -# local frames=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏) -# local spin_i=0 -# local interval=0.1 - -# SPINNER_MSG="$msg" -# printf "\r\e[2K" >&2 - -# { -# while [[ "$SPINNER_ACTIVE" -eq 1 ]]; do -# printf "\r\e[2K%s %b" "${frames[spin_i]}" "${YW}${SPINNER_MSG}${CL}" >&2 -# spin_i=$(((spin_i + 1) % ${#frames[@]})) -# sleep "$interval" -# done -# } & - -# SPINNER_PID=$! -# disown "$SPINNER_PID" -# } - -# stop_spinner() { -# if [[ ${SPINNER_PID+v} && -n "$SPINNER_PID" ]] && kill -0 "$SPINNER_PID" 2>/dev/null; then -# kill "$SPINNER_PID" 2>/dev/null -# sleep 0.1 -# kill -0 "$SPINNER_PID" 2>/dev/null && kill -9 "$SPINNER_PID" 2>/dev/null -# wait "$SPINNER_PID" 2>/dev/null || true -# fi -# SPINNER_ACTIVE=0 -# unset SPINNER_PID -# } - -# spinner_guard() { -# if [[ "$SPINNER_ACTIVE" -eq 1 ]] && [[ -n "$SPINNER_PID" ]]; then -# kill "$SPINNER_PID" 2>/dev/null -# wait "$SPINNER_PID" 2>/dev/null || true -# SPINNER_ACTIVE=0 -# unset SPINNER_PID -# fi -# } - -# msg_info() { -# local msg="$1" -# [[ -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return -# MSG_INFO_SHOWN["$msg"]=1 - -# spinner_guard -# SPINNER_ACTIVE=1 -# start_spinner "$msg" -# } - -# msg_ok() { -# local msg="$1" -# stop_spinner -# printf "\r\e[2K%s %b\n" "${CM}" "${GN}${msg}${CL}" >&2 -# unset MSG_INFO_SHOWN["$msg"] -# } - -# msg_error() { -# stop_spinner -# local msg="$1" -# printf "\r\e[2K%s %b\n" "${CROSS}" "${RD}${msg}${CL}" >&2 -# #log_message "ERROR" "$msg" -# } - -# log_message() { -# local level="$1" -# local message="$2" -# local timestamp -# local logdate -# timestamp=$(date '+%Y-%m-%d %H:%M:%S') -# logdate=$(date '+%Y-%m-%d') - -# LOGDIR="/usr/local/community-scripts/logs" -# mkdir -p "$LOGDIR" - -# LOGFILE="${LOGDIR}/${logdate}_${NSAPP}.log" -# echo "$timestamp - $level: $message" >>"$LOGFILE" -# } - # Check if the shell is using bash shell_check() { - if [[ "$(basename "$SHELL")" != "bash" ]]; then - clear - msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." - echo -e "\nExiting..." - sleep 2 - exit - fi + if [[ "$(basename "$SHELL")" != "bash" ]]; then + clear + msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." + echo -e "\nExiting..." + sleep 2 + exit + fi } # Run as root only root_check() { - if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then - clear - msg_error "Please run this script as root." - echo -e "\nExiting..." - sleep 2 - exit - fi + if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit + fi } # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { - if ! pveversion | grep -Eq "pve-manager/8\.[0-4](\.[0-9]+)*"; then - msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported" - echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." - echo -e "Exiting..." - sleep 2 - exit - fi + if ! pveversion | grep -Eq "pve-manager/8\.[0-4](\.[0-9]+)*"; then + msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported" + echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." + echo -e "Exiting..." + sleep 2 + exit + fi } # When a node is running tens of containers, it's possible to exceed the kernel's cryptographic key storage allocations. # These are tuneable, so verify if the currently deployment is approaching the limits, advise the user on how to tune the limits, and exit the script. # https://cleveruptime.com/docs/files/proc-key-users | https://docs.kernel.org/security/keys/core.html maxkeys_check() { - # Read kernel parameters - per_user_maxkeys=$(cat /proc/sys/kernel/keys/maxkeys 2>/dev/null || echo 0) - per_user_maxbytes=$(cat /proc/sys/kernel/keys/maxbytes 2>/dev/null || echo 0) + # Read kernel parameters + per_user_maxkeys=$(cat /proc/sys/kernel/keys/maxkeys 2>/dev/null || echo 0) + per_user_maxbytes=$(cat /proc/sys/kernel/keys/maxbytes 2>/dev/null || echo 0) - # Exit if kernel parameters are unavailable - if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then - echo -e "${CROSS}${RD} Error: Unable to read kernel parameters. Ensure proper permissions.${CL}" - exit 1 - fi + # Exit if kernel parameters are unavailable + if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then + echo -e "${CROSS}${RD} Error: Unable to read kernel parameters. Ensure proper permissions.${CL}" + exit 1 + fi - # Fetch key usage for user ID 100000 (typical for containers) - used_lxc_keys=$(awk '/100000:/ {print $2}' /proc/key-users 2>/dev/null || echo 0) - used_lxc_bytes=$(awk '/100000:/ {split($5, a, "/"); print a[1]}' /proc/key-users 2>/dev/null || echo 0) + # Fetch key usage for user ID 100000 (typical for containers) + used_lxc_keys=$(awk '/100000:/ {print $2}' /proc/key-users 2>/dev/null || echo 0) + used_lxc_bytes=$(awk '/100000:/ {split($5, a, "/"); print a[1]}' /proc/key-users 2>/dev/null || echo 0) - # Calculate thresholds and suggested new limits - threshold_keys=$((per_user_maxkeys - 100)) - threshold_bytes=$((per_user_maxbytes - 1000)) - new_limit_keys=$((per_user_maxkeys * 2)) - new_limit_bytes=$((per_user_maxbytes * 2)) + # Calculate thresholds and suggested new limits + threshold_keys=$((per_user_maxkeys - 100)) + threshold_bytes=$((per_user_maxbytes - 1000)) + new_limit_keys=$((per_user_maxkeys * 2)) + new_limit_bytes=$((per_user_maxbytes * 2)) - # Check if key or byte usage is near limits - failure=0 - if [[ "$used_lxc_keys" -gt "$threshold_keys" ]]; then - echo -e "${CROSS}${RD} Warning: Key usage is near the limit (${used_lxc_keys}/${per_user_maxkeys}).${CL}" - echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxkeys=${new_limit_keys}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." - failure=1 - fi - if [[ "$used_lxc_bytes" -gt "$threshold_bytes" ]]; then - echo -e "${CROSS}${RD} Warning: Key byte usage is near the limit (${used_lxc_bytes}/${per_user_maxbytes}).${CL}" - echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxbytes=${new_limit_bytes}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." - failure=1 - fi + # Check if key or byte usage is near limits + failure=0 + if [[ "$used_lxc_keys" -gt "$threshold_keys" ]]; then + echo -e "${CROSS}${RD} Warning: Key usage is near the limit (${used_lxc_keys}/${per_user_maxkeys}).${CL}" + echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxkeys=${new_limit_keys}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." + failure=1 + fi + if [[ "$used_lxc_bytes" -gt "$threshold_bytes" ]]; then + echo -e "${CROSS}${RD} Warning: Key byte usage is near the limit (${used_lxc_bytes}/${per_user_maxbytes}).${CL}" + echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxbytes=${new_limit_bytes}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." + failure=1 + fi - # Provide next steps if issues are detected - if [[ "$failure" -eq 1 ]]; then - echo -e "${INFO} To apply changes, run: ${BOLD}service procps force-reload${CL}" - exit 1 - fi + # Provide next steps if issues are detected + if [[ "$failure" -eq 1 ]]; then + echo -e "${INFO} To apply changes, run: ${BOLD}service procps force-reload${CL}" + exit 1 + fi - echo -e "${CM}${GN} All kernel key limits are within safe thresholds.${CL}" + echo -e "${CM}${GN} All kernel key limits are within safe thresholds.${CL}" } # This function checks the system architecture and exits if it's not "amd64". arch_check() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n" - echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" - echo -e "Exiting..." - sleep 2 - exit - fi + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n" + echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" + echo -e "Exiting..." + sleep 2 + exit + fi } # Function to get the current IP address based on the distribution get_current_ip() { - if [ -f /etc/os-release ]; then - # Check for Debian/Ubuntu (uses hostname -I) - if grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then - CURRENT_IP=$(hostname -I | awk '{print $1}') - # Check for Alpine (uses ip command) - elif grep -q 'ID=alpine' /etc/os-release; then - CURRENT_IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) - else - CURRENT_IP="Unknown" - fi + if [ -f /etc/os-release ]; then + # Check for Debian/Ubuntu (uses hostname -I) + if grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then + CURRENT_IP=$(hostname -I | awk '{print $1}') + # Check for Alpine (uses ip command) + elif grep -q 'ID=alpine' /etc/os-release; then + CURRENT_IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) + else + CURRENT_IP="Unknown" fi - echo "$CURRENT_IP" + fi + echo "$CURRENT_IP" } # Function to update the IP address in the MOTD file update_motd_ip() { - MOTD_FILE="/etc/motd" + MOTD_FILE="/etc/motd" - if [ -f "$MOTD_FILE" ]; then - # Remove existing IP Address lines to prevent duplication - sed -i '/IP Address:/d' "$MOTD_FILE" + if [ -f "$MOTD_FILE" ]; then + # Remove existing IP Address lines to prevent duplication + sed -i '/IP Address:/d' "$MOTD_FILE" - IP=$(get_current_ip) - # Add the new IP address - echo -e "${TAB}${NETWORK}${YW} IP Address: ${GN}${IP}${CL}" >>"$MOTD_FILE" - fi + IP=$(get_current_ip) + # Add the new IP address + echo -e "${TAB}${NETWORK}${YW} IP Address: ${GN}${IP}${CL}" >>"$MOTD_FILE" + fi } # Function to download & save header files get_header() { - local app_name=$(echo "${APP,,}" | tr -d ' ') - local header_url="https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/ct/headers/${app_name}" - local local_header_path="/usr/local/community-scripts/headers/${app_name}" + local app_name=$(echo "${APP,,}" | tr -d ' ') + local header_url="https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/ct/headers/${app_name}" + local local_header_path="/usr/local/community-scripts/headers/${app_name}" - mkdir -p "$(dirname "$local_header_path")" + mkdir -p "$(dirname "$local_header_path")" - if [ ! -s "$local_header_path" ]; then - if ! curl -fsSL "$header_url" -o "$local_header_path"; then - return 1 - fi + if [ ! -s "$local_header_path" ]; then + if ! curl -fsSL "$header_url" -o "$local_header_path"; then + return 1 fi + fi - cat "$local_header_path" 2>/dev/null || true + cat "$local_header_path" 2>/dev/null || true } # This function sets the APP-Name into an ASCII Header in Slant, figlet needed on proxmox main node. header_info() { - local app_name=$(echo "${APP,,}" | tr -d ' ') - local header_content + local app_name=$(echo "${APP,,}" | tr -d ' ') + local header_content - # Download & save Header-File locally - header_content=$(get_header "$app_name") || header_content="" + # Download & save Header-File locally + header_content=$(get_header "$app_name") || header_content="" - # Show ASCII-Header - clear - local term_width - term_width=$(tput cols 2>/dev/null || echo 120) + # Show ASCII-Header + clear + local term_width + term_width=$(tput cols 2>/dev/null || echo 120) - if [ -n "$header_content" ]; then - echo "$header_content" - fi + if [ -n "$header_content" ]; then + echo "$header_content" + fi } # This function checks if the script is running through SSH and prompts the user to confirm if they want to proceed or exit. ssh_check() { - if [ -n "${SSH_CLIENT:+x}" ]; then - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's advisable to utilize the Proxmox shell rather than SSH, as there may be potential complications with variable retrieval. Proceed using SSH?" 10 72; then - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Proceed using SSH" "You've chosen to proceed using SSH. If any issues arise, please run the script in the Proxmox shell before creating a repository issue." 10 72 - else - clear - echo "Exiting due to SSH usage. Please consider using the Proxmox shell." - exit - fi + if [ -n "${SSH_CLIENT:+x}" ]; then + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's advisable to utilize the Proxmox shell rather than SSH, as there may be potential complications with variable retrieval. Proceed using SSH?" 10 72; then + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Proceed using SSH" "You've chosen to proceed using SSH. If any issues arise, please run the script in the Proxmox shell before creating a repository issue." 10 72 + else + clear + echo "Exiting due to SSH usage. Please consider using the Proxmox shell." + exit fi + fi } base_settings() { - # Default Settings - CT_TYPE="1" - DISK_SIZE="4" - CORE_COUNT="1" - RAM_SIZE="1024" - VERBOSE="${1:-no}" - PW="" - CT_ID=$NEXTID - HN=$NSAPP - BRG="vmbr0" - NET="dhcp" - GATE="" - APT_CACHER="" - APT_CACHER_IP="" - DISABLEIP6="no" - MTU="" - SD="" - NS="" - MAC="" - VLAN="" - SSH="no" - SSH_AUTHORIZED_KEY="" - TAGS="community-script;" - UDHCPC_FIX="" + # Default Settings + CT_TYPE="1" + DISK_SIZE="4" + CORE_COUNT="1" + RAM_SIZE="1024" + VERBOSE="${1:-no}" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + SSH_AUTHORIZED_KEY="" + TAGS="community-script;" + UDHCPC_FIX="" - # Override default settings with variables from ct script - CT_TYPE=${var_unprivileged:-$CT_TYPE} - DISK_SIZE=${var_disk:-$DISK_SIZE} - CORE_COUNT=${var_cpu:-$CORE_COUNT} - RAM_SIZE=${var_ram:-$RAM_SIZE} - VERB=${var_verbose:-$VERBOSE} - TAGS="${TAGS}${var_tags:-}" + # Override default settings with variables from ct script + CT_TYPE=${var_unprivileged:-$CT_TYPE} + DISK_SIZE=${var_disk:-$DISK_SIZE} + CORE_COUNT=${var_cpu:-$CORE_COUNT} + RAM_SIZE=${var_ram:-$RAM_SIZE} + VERB=${var_verbose:-$VERBOSE} + TAGS="${TAGS}${var_tags:-}" - # Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts - if [ -z "$var_os" ]; then - var_os="debian" - fi - if [ -z "$var_version" ]; then - var_version="12" - fi + # Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts + if [ -z "$var_os" ]; then + var_os="debian" + fi + if [ -z "$var_version" ]; then + var_version="12" + fi } # This function displays the default values for various settings. echo_default() { - # Convert CT_TYPE to description - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi + # Convert CT_TYPE to description + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi - # Output the selected values with icons - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" - echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" - if [ "$VERB" == "yes" ]; then - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}" - fi - echo -e "${CREATING}${BOLD}${BL}Creating a ${APP} LXC using the above default settings${CL}" - echo -e " " + # Output the selected values with icons + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" + echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" + echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" + echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" + if [ "$VERB" == "yes" ]; then + echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}" + fi + echo -e "${CREATING}${BOLD}${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e " " } # This function is called when the user decides to exit the script. It clears the screen and displays an exit message. exit_script() { - [[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" &>/dev/null || true - clear - echo -e "\n${CROSS}${RD}User exited script${CL}\n" - exit + [[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" &>/dev/null || true + clear + echo -e "\n${CROSS}${RD}User exited script${CL}\n" + exit } # This function allows the user to configure advanced settings for the script. advanced_settings() { - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 - # Setting Default Tag for Advanced Settings - TAGS="community-script;${var_tags:-}" - CT_DEFAULT_TYPE="${CT_TYPE}" - CT_TYPE="" - while [ -z "$CT_TYPE" ]; do - if [ "$CT_DEFAULT_TYPE" == "1" ]; then - if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - if [ -n "$CT_TYPE" ]; then - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - fi - else - exit_script - fi + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 + # Setting Default Tag for Advanced Settings + TAGS="community-script;${var_tags:-}" + CT_DEFAULT_TYPE="${CT_TYPE}" + CT_TYPE="" + while [ -z "$CT_TYPE" ]; do + if [ "$CT_DEFAULT_TYPE" == "1" ]; then + if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then + if [ -n "$CT_TYPE" ]; then + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" + echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" fi - if [ "$CT_DEFAULT_TYPE" == "0" ]; then - if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3); then - if [ -n "$CT_TYPE" ]; then - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - fi - else - exit_script - fi + else + exit_script + fi + fi + if [ "$CT_DEFAULT_TYPE" == "0" ]; then + if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3); then + if [ -n "$CT_TYPE" ]; then + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" + echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" fi - done + else + exit_script + fi + fi + done - while true; do - if PW1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD (leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [[ ! -z "$PW1" ]]; then - if [[ "$PW1" == *" "* ]]; then - whiptail --msgbox "Password cannot contain spaces. Please try again." 8 58 - elif [ ${#PW1} -lt 5 ]; then - whiptail --msgbox "Password must be at least 5 characters long. Please try again." 8 58 - else - if PW2=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nVerify Root Password" 9 58 --title "PASSWORD VERIFICATION" 3>&1 1>&2 2>&3); then - if [[ "$PW1" == "$PW2" ]]; then - PW="-password $PW1" - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}********${CL}" - break - else - whiptail --msgbox "Passwords do not match. Please try again." 8 58 - fi - else - exit_script - fi - fi - else - PW1="Automatic Login" - PW="" - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}$PW1${CL}" - break - fi + while true; do + if PW1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD (leave blank for automatic login)" 3>&1 1>&2 2>&3); then + if [[ ! -z "$PW1" ]]; then + if [[ "$PW1" == *" "* ]]; then + whiptail --msgbox "Password cannot contain spaces. Please try again." 8 58 + elif [ ${#PW1} -lt 5 ]; then + whiptail --msgbox "Password must be at least 5 characters long. Please try again." 8 58 else + if PW2=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nVerify Root Password" 9 58 --title "PASSWORD VERIFICATION" 3>&1 1>&2 2>&3); then + if [[ "$PW1" == "$PW2" ]]; then + PW="-password $PW1" + echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}********${CL}" + break + else + whiptail --msgbox "Passwords do not match. Please try again." 8 58 + fi + else exit_script + fi fi - done - - if CT_ID=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 "$NEXTID" --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi + else + PW1="Automatic Login" + PW="" + echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}$PW1${CL}" + break + fi else - exit + exit_script fi + done - if CT_NAME=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 "$NSAPP" --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo "${CT_NAME,,}" | tr -d ' ') - fi - echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}" + if CT_ID=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 "$NEXTID" --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" else - exit_script + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" fi + else + exit + fi - if DISK_SIZE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GB" 8 58 "$var_disk" --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "{INFO}${HOLD}${RD} DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" - fi + if CT_NAME=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 "$NSAPP" --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" else - exit_script + HN=$(echo "${CT_NAME,,}" | tr -d ' ') fi + echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}" + else + exit_script + fi - if CORE_COUNT=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 "$var_cpu" --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}" - fi + if DISK_SIZE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GB" 8 58 "$var_disk" --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" else - exit_script - fi - - if RAM_SIZE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 "$var_ram" --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - else - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - fi - else - exit_script - fi - - if BRG=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" - else - echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" - fi - else - exit_script - fi - - while true; do - NET=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Static IPv4 CIDR Address (/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) - exit_status=$? - if [ $exit_status -eq 0 ]; then - if [ "$NET" = "dhcp" ]; then - echo -e "${NETWORK}${BOLD}${DGN}IP Address: ${BGN}$NET${CL}" - break - else - if [[ "$NET" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then - echo -e "${NETWORK}${BOLD}${DGN}IP Address: ${BGN}$NET${CL}" - break - else - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox "$NET is an invalid IPv4 CIDR address. Please enter a valid IPv4 CIDR address or 'dhcp'" 8 58 - fi - fi - else - exit_script - fi - done - - if [ "$NET" != "dhcp" ]; then - while true; do - GATE1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Enter gateway IP address" 8 58 --title "Gateway IP" 3>&1 1>&2 2>&3) - if [ -z "$GATE1" ]; then - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox "Gateway IP address cannot be empty" 8 58 - elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox "Invalid IP address format" 8 58 - else - GATE=",gw=$GATE1" - echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}$GATE1${CL}" - break - fi - done - else - GATE="" - echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}Default${CL}" - fi - - if [ "$var_os" == "alpine" ]; then - APT_CACHER="" - APT_CACHER_IP="" - else - if APT_CACHER_IP=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for none)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then - APT_CACHER="${APT_CACHER_IP:+yes}" - echo -e "${NETWORK}${BOLD}${DGN}APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" - else - exit_script - fi - fi - - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" - else - DISABLEIP6="no" - fi - echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - - if MTU1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default [The MTU of your selected vmbr, default is 1500])" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$MTU1" ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}" - else - exit_script - fi - - if SD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z "$SD" ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}$SX${CL}" - else - exit_script - fi - - if NX=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z "$NX" ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}$NX${CL}" - else - exit_script - fi - - if [ "$var_os" == "alpine" ] && [ "$NET" == "dhcp" ] && [ "$NX" != "Host" ]; then - UDHCPC_FIX="yes" - else - UDHCPC_FIX="no" - fi - export UDHCPC_FIX - - if MAC1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a MAC Address(leave blank for generated MAC)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z "$MAC1" ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}" - fi - else - exit_script - fi - - if VLAN1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for no VLAN)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z "$VLAN1" ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${VLANTAG}${BOLD}${DGN}Vlan: ${BGN}$VLAN1${CL}" - else - exit_script - fi - - if ADV_TAGS=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Custom Tags?[If you remove all, there will be no tags!]" 8 58 "${TAGS}" --title "Advanced Tags" 3>&1 1>&2 2>&3); then - if [ -n "${ADV_TAGS}" ]; then - ADV_TAGS=$(echo "$ADV_TAGS" | tr -d '[:space:]') - TAGS="${ADV_TAGS}" - else - TAGS=";" - fi - echo -e "${NETWORK}${BOLD}${DGN}Tags: ${BGN}$TAGS${CL}" - else - exit_script - fi - - if [[ "$PW" == -password* ]]; then - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" - else - SSH="no" - fi - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - else - SSH="no" - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - fi - - if [[ "${SSH}" == "yes" ]]; then - SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "SSH Authorized key for root (leave empty for none)" 8 58 --title "SSH Key" 3>&1 1>&2 2>&3)" - - if [[ -z "${SSH_AUTHORIZED_KEY}" ]]; then - echo "Warning: No SSH key provided." - fi - else - SSH_AUTHORIZED_KEY="" - fi - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" - else - VERB="no" - fi - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERB${CL}" - - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "{INFO}${HOLD}${RD} DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" advanced_settings + fi + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" fi + else + exit_script + fi + + if CORE_COUNT=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 "$var_cpu" --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}" + fi + else + exit_script + fi + + if RAM_SIZE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 "$var_ram" --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" + else + echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" + fi + else + exit_script + fi + + if BRG=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" + else + echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" + fi + else + exit_script + fi + + while true; do + NET=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Static IPv4 CIDR Address (/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) + exit_status=$? + if [ $exit_status -eq 0 ]; then + if [ "$NET" = "dhcp" ]; then + echo -e "${NETWORK}${BOLD}${DGN}IP Address: ${BGN}$NET${CL}" + break + else + if [[ "$NET" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then + echo -e "${NETWORK}${BOLD}${DGN}IP Address: ${BGN}$NET${CL}" + break + else + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox "$NET is an invalid IPv4 CIDR address. Please enter a valid IPv4 CIDR address or 'dhcp'" 8 58 + fi + fi + else + exit_script + fi + done + + if [ "$NET" != "dhcp" ]; then + while true; do + GATE1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Enter gateway IP address" 8 58 --title "Gateway IP" 3>&1 1>&2 2>&3) + if [ -z "$GATE1" ]; then + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox "Gateway IP address cannot be empty" 8 58 + elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox "Invalid IP address format" 8 58 + else + GATE=",gw=$GATE1" + echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}$GATE1${CL}" + break + fi + done + else + GATE="" + echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}Default${CL}" + fi + + if [ "$var_os" == "alpine" ]; then + APT_CACHER="" + APT_CACHER_IP="" + else + if APT_CACHER_IP=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for none)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then + APT_CACHER="${APT_CACHER_IP:+yes}" + echo -e "${NETWORK}${BOLD}${DGN}APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" + else + exit_script + fi + fi + + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" + else + DISABLEIP6="no" + fi + echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + + if MTU1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default [The MTU of your selected vmbr, default is 1500])" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$MTU1" ]; then + MTU1="Default" + MTU="" + else + MTU=",mtu=$MTU1" + fi + echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}" + else + exit_script + fi + + if SD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then + if [ -z "$SD" ]; then + SX=Host + SD="" + else + SX=$SD + SD="-searchdomain=$SD" + fi + echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}$SX${CL}" + else + exit_script + fi + + if NX=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z "$NX" ]; then + NX=Host + NS="" + else + NS="-nameserver=$NX" + fi + echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}$NX${CL}" + else + exit_script + fi + + if [ "$var_os" == "alpine" ] && [ "$NET" == "dhcp" ] && [ "$NX" != "Host" ]; then + UDHCPC_FIX="yes" + else + UDHCPC_FIX="no" + fi + export UDHCPC_FIX + + if MAC1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a MAC Address(leave blank for generated MAC)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z "$MAC1" ]; then + MAC1="Default" + MAC="" + else + MAC=",hwaddr=$MAC1" + echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}" + fi + else + exit_script + fi + + if VLAN1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for no VLAN)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then + if [ -z "$VLAN1" ]; then + VLAN1="Default" + VLAN="" + else + VLAN=",tag=$VLAN1" + fi + echo -e "${VLANTAG}${BOLD}${DGN}Vlan: ${BGN}$VLAN1${CL}" + else + exit_script + fi + + if ADV_TAGS=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Custom Tags?[If you remove all, there will be no tags!]" 8 58 "${TAGS}" --title "Advanced Tags" 3>&1 1>&2 2>&3); then + if [ -n "${ADV_TAGS}" ]; then + ADV_TAGS=$(echo "$ADV_TAGS" | tr -d '[:space:]') + TAGS="${ADV_TAGS}" + else + TAGS=";" + fi + echo -e "${NETWORK}${BOLD}${DGN}Tags: ${BGN}$TAGS${CL}" + else + exit_script + fi + + if [[ "$PW" == -password* ]]; then + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" + else + SSH="no" + fi + echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" + else + SSH="no" + echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" + fi + + if [[ "${SSH}" == "yes" ]]; then + SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "SSH Authorized key for root (leave empty for none)" 8 58 --title "SSH Key" 3>&1 1>&2 2>&3)" + + if [[ -z "${SSH_AUTHORIZED_KEY}" ]]; then + echo "Warning: No SSH key provided." + fi + else + SSH_AUTHORIZED_KEY="" + fi + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" + else + VERB="no" + fi + echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERB${CL}" + + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" + advanced_settings + fi } diagnostics_check() { - if ! [ -d "/usr/local/community-scripts" ]; then - mkdir -p /usr/local/community-scripts - fi + if ! [ -d "/usr/local/community-scripts" ]; then + mkdir -p /usr/local/community-scripts + fi - if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then - cat </usr/local/community-scripts/diagnostics + if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then + cat </usr/local/community-scripts/diagnostics DIAGNOSTICS=yes #This file is used to store the diagnostics settings for the Community-Scripts API. @@ -765,9 +677,9 @@ DIAGNOSTICS=yes #"status" #If you have any concerns, please review the source code at /misc/build.func EOF - DIAGNOSTICS="yes" - else - cat </usr/local/community-scripts/diagnostics + DIAGNOSTICS="yes" + else + cat </usr/local/community-scripts/diagnostics DIAGNOSTICS=no #This file is used to store the diagnostics settings for the Community-Scripts API. @@ -792,537 +704,537 @@ DIAGNOSTICS=no #"status" #If you have any concerns, please review the source code at /misc/build.func EOF - DIAGNOSTICS="no" - fi - else - DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' /usr/local/community-scripts/diagnostics) - + DIAGNOSTICS="no" fi + else + DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' /usr/local/community-scripts/diagnostics) + + fi } config_file() { - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Default distribution for $APP" "${var_os} ${var_version} \n \nIf the default Linux distribution is not adhered to, script support will be discontinued. \n" 10 58 + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Default distribution for $APP" "${var_os} ${var_version} \n \nIf the default Linux distribution is not adhered to, script support will be discontinued. \n" 10 58 - CONFIG_FILE="/opt/community-scripts/.settings" + CONFIG_FILE="/opt/community-scripts/.settings" - if [[ -f "/opt/community-scripts/${NSAPP}.conf" ]]; then - CONFIG_FILE="/opt/community-scripts/${NSAPP}.conf" - fi + if [[ -f "/opt/community-scripts/${NSAPP}.conf" ]]; then + CONFIG_FILE="/opt/community-scripts/${NSAPP}.conf" + fi - if CONFIG_FILE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set absolute path to config file" 8 58 "$CONFIG_FILE" --title "CONFIG FILE" 3>&1 1>&2 2>&3); then - if [[ ! -f "$CONFIG_FILE" ]]; then - echo -e "${CROSS}${RD}Config file not found, exiting script!.${CL}" - exit - else - echo -e "${INFO}${BOLD}${DGN}Using config File: ${BGN}$CONFIG_FILE${CL}" - base_settings - source "$CONFIG_FILE" - fi - fi - - if [[ "$var_os" == "debian" ]]; then - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - if [[ "$var_version" == "11" ]]; then - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - elif [[ "$var_version" == "12" ]]; then - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - else - msg_error "Unknown setting for var_version, should be 11 or 12, was ${var_version}" - exit - fi - elif [[ "$var_os" == "ubuntu" ]]; then - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - if [[ "$var_version" == "20.04" ]]; then - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - elif [[ "$var_version" == "22.04" ]]; then - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - elif [[ "$var_version" == "24.04" ]]; then - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - elif [[ "$var_version" == "24.10" ]]; then - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - else - msg_error "Unknown setting for var_version, should be 20.04, 22.04, 24.04 or 24.10, was ${var_version}" - exit - fi + if CONFIG_FILE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set absolute path to config file" 8 58 "$CONFIG_FILE" --title "CONFIG FILE" 3>&1 1>&2 2>&3); then + if [[ ! -f "$CONFIG_FILE" ]]; then + echo -e "${CROSS}${RD}Config file not found, exiting script!.${CL}" + exit else - msg_error "Unknown setting for var_os! should be debian or ubuntu, was ${var_os}" + echo -e "${INFO}${BOLD}${DGN}Using config File: ${BGN}$CONFIG_FILE${CL}" + base_settings + source "$CONFIG_FILE" + fi + fi + + if [[ "$var_os" == "debian" ]]; then + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" + if [[ "$var_version" == "11" ]]; then + echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + elif [[ "$var_version" == "12" ]]; then + echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + else + msg_error "Unknown setting for var_version, should be 11 or 12, was ${var_version}" + exit + fi + elif [[ "$var_os" == "ubuntu" ]]; then + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" + if [[ "$var_version" == "20.04" ]]; then + echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + elif [[ "$var_version" == "22.04" ]]; then + echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + elif [[ "$var_version" == "24.04" ]]; then + echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + elif [[ "$var_version" == "24.10" ]]; then + echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + else + msg_error "Unknown setting for var_version, should be 20.04, 22.04, 24.04 or 24.10, was ${var_version}" + exit + fi + else + msg_error "Unknown setting for var_os! should be debian or ubuntu, was ${var_os}" + exit + fi + + if [[ -n "$CT_ID" ]]; then + + if [[ "$CT_ID" =~ ^([0-9]{3,4})-([0-9]{3,4})$ ]]; then + MIN_ID=${BASH_REMATCH[1]} + MAX_ID=${BASH_REMATCH[2]} + + if ((MIN_ID >= MAX_ID)); then + msg_error "Invalid Container ID range. The first number must be smaller than the second number, was ${CT_ID}" exit - fi + fi - if [[ -n "$CT_ID" ]]; then + LIST_OF_IDS=$(pvesh get /cluster/resources --type vm --output-format json | grep -oP '"vmid":\s*\K\d+') - if [[ "$CT_ID" =~ ^([0-9]{3,4})-([0-9]{3,4})$ ]]; then - MIN_ID=${BASH_REMATCH[1]} - MAX_ID=${BASH_REMATCH[2]} - - if ((MIN_ID >= MAX_ID)); then - msg_error "Invalid Container ID range. The first number must be smaller than the second number, was ${CT_ID}" - exit - fi - - LIST_OF_IDS=$(pvesh get /cluster/resources --type vm --output-format json | grep -oP '"vmid":\s*\K\d+') - - for ((ID = MIN_ID; ID <= MAX_ID; ID++)); do - if ! grep -q "^$ID$" <<<"$LIST_OF_IDS"; then - CT_ID=$ID - break - fi - done - - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - - elif [[ "$CT_ID" =~ ^[0-9]+$ ]]; then - - LIST_OF_IDS=$(pvesh get /cluster/resources --type vm --output-format json | grep -oP '"vmid":\s*\K\d+') - if ! grep -q "^$CT_ID$" <<<"$LIST_OF_IDS"; then - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - msg_error "Container ID $CT_ID already exists" - exit - fi - else - msg_error "Invalid Container ID format. Needs to be 0000-9999 or 0-9999, was ${CT_ID}" - exit + for ((ID = MIN_ID; ID <= MAX_ID; ID++)); do + if ! grep -q "^$ID$" <<<"$LIST_OF_IDS"; then + CT_ID=$ID + break fi - fi + done - if [[ "$CT_TYPE" -eq 0 ]]; then - CT_TYPE_DESC="Privileged" - elif [[ "$CT_TYPE" -eq 1 ]]; then - CT_TYPE_DESC="Unprivileged" - else - msg_error "Unknown setting for CT_TYPE, should be 1 or 0, was ${CT_TYPE}" + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" + + elif [[ "$CT_ID" =~ ^[0-9]+$ ]]; then + + LIST_OF_IDS=$(pvesh get /cluster/resources --type vm --output-format json | grep -oP '"vmid":\s*\K\d+') + if ! grep -q "^$CT_ID$" <<<"$LIST_OF_IDS"; then + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + msg_error "Container ID $CT_ID already exists" exit - fi - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - - if [[ ! -z "$PW" ]]; then - - if [[ "$PW" == *" "* ]]; then - msg_error "Password cannot be empty" - exit - elif [[ ${#PW} -lt 5 ]]; then - msg_error "Password must be at least 5 characters long" - exit - else - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}********${CL}" - fi - PW="-password $PW" + fi else - PW="" - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}Automatic Login${CL}" + msg_error "Invalid Container ID format. Needs to be 0000-9999 or 0-9999, was ${CT_ID}" + exit fi - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi - if [[ ! -z "$HN" ]]; then - echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}" + if [[ "$CT_TYPE" -eq 0 ]]; then + CT_TYPE_DESC="Privileged" + elif [[ "$CT_TYPE" -eq 1 ]]; then + CT_TYPE_DESC="Unprivileged" + else + msg_error "Unknown setting for CT_TYPE, should be 1 or 0, was ${CT_TYPE}" + exit + fi + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" + + if [[ ! -z "$PW" ]]; then + + if [[ "$PW" == *" "* ]]; then + msg_error "Password cannot be empty" + exit + elif [[ ${#PW} -lt 5 ]]; then + msg_error "Password must be at least 5 characters long" + exit else - msg_error "Hostname cannot be empty" - exit + echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}********${CL}" fi + PW="-password $PW" + else + PW="" + echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}Automatic Login${CL}" + fi + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - if [[ ! -z "$DISK_SIZE" ]]; then - if [[ "$DISK_SIZE" =~ ^-?[0-9]+$ ]]; then - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" - else - msg_error "DISK_SIZE must be an integer, was ${DISK_SIZE}" - exit - fi + if [[ ! -z "$HN" ]]; then + echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}" + else + msg_error "Hostname cannot be empty" + exit + fi + + if [[ ! -z "$DISK_SIZE" ]]; then + if [[ "$DISK_SIZE" =~ ^-?[0-9]+$ ]]; then + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" else - msg_error "DISK_SIZE cannot be empty" - exit + msg_error "DISK_SIZE must be an integer, was ${DISK_SIZE}" + exit fi + else + msg_error "DISK_SIZE cannot be empty" + exit + fi - if [[ ! -z "$CORE_COUNT" ]]; then - if [[ "$CORE_COUNT" =~ ^-?[0-9]+$ ]]; then - echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" - else - msg_error "CORE_COUNT must be an integer, was ${CORE_COUNT}" - exit - fi + if [[ ! -z "$CORE_COUNT" ]]; then + if [[ "$CORE_COUNT" =~ ^-?[0-9]+$ ]]; then + echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" else - msg_error "CORE_COUNT cannot be empty" - exit + msg_error "CORE_COUNT must be an integer, was ${CORE_COUNT}" + exit fi + else + msg_error "CORE_COUNT cannot be empty" + exit + fi - if [[ ! -z "$RAM_SIZE" ]]; then - if [[ "$RAM_SIZE" =~ ^-?[0-9]+$ ]]; then - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - else - msg_error "RAM_SIZE must be an integer, was ${RAM_SIZE}" - exit - fi + if [[ ! -z "$RAM_SIZE" ]]; then + if [[ "$RAM_SIZE" =~ ^-?[0-9]+$ ]]; then + echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" else - msg_error "RAM_SIZE cannot be empty" - exit + msg_error "RAM_SIZE must be an integer, was ${RAM_SIZE}" + exit fi + else + msg_error "RAM_SIZE cannot be empty" + exit + fi - if [[ ! -z "$BRG" ]]; then - if grep -q "^iface ${BRG}" /etc/network/interfaces; then - echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" - else - msg_error "Bridge '${BRG}' does not exist in /etc/network/interfaces" - exit - fi + if [[ ! -z "$BRG" ]]; then + if grep -q "^iface ${BRG}" /etc/network/interfaces; then + echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" else - msg_error "Bridge cannot be empty" - exit + msg_error "Bridge '${BRG}' does not exist in /etc/network/interfaces" + exit fi + else + msg_error "Bridge cannot be empty" + exit + fi - local ip_cidr_regex='^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/([0-9]{1,2})$' - local ip_regex='^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$' + local ip_cidr_regex='^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/([0-9]{1,2})$' + local ip_regex='^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$' - if [[ ! -z $NET ]]; then - if [ "$NET" == "dhcp" ]; then - echo -e "${NETWORK}${BOLD}${DGN}IP Address: ${BGN}DHCP${CL}" - echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}Default${CL}" - elif - [[ "$NET" =~ $ip_cidr_regex ]] - then - echo -e "${NETWORK}${BOLD}${DGN}IP Address: ${BGN}$NET${CL}" - else - msg_error "Invalid IP Address format. Needs to be 0.0.0.0/0, was ${NET}" - exit - fi - fi - if [ ! -z "$GATE" ]; then - if [[ "$GATE" =~ $ip_regex ]]; then - echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}$GATE${CL}" - GATE=",gw=$GATE" - else - msg_error "Invalid IP Address format for Gateway. Needs to be 0.0.0.0, was ${GATE}" - exit - fi + if [[ ! -z $NET ]]; then + if [ "$NET" == "dhcp" ]; then + echo -e "${NETWORK}${BOLD}${DGN}IP Address: ${BGN}DHCP${CL}" + echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}Default${CL}" + elif + [[ "$NET" =~ $ip_cidr_regex ]] + then + echo -e "${NETWORK}${BOLD}${DGN}IP Address: ${BGN}$NET${CL}" else - msg_error "Gateway IP Address cannot be empty" - exit + msg_error "Invalid IP Address format. Needs to be 0.0.0.0/0, was ${NET}" + exit fi - - if [[ ! -z "$APT_CACHER_IP" ]]; then - if [[ "$APT_CACHER_IP" =~ $ip_regex ]]; then - APT_CACHER="yes" - echo -e "${NETWORK}${BOLD}${DGN}APT-CACHER IP Address: ${BGN}$APT_CACHER_IP${CL}" - else - msg_error "Invalid IP Address format for APT-Cacher. Needs to be 0.0.0.0, was ${APT_CACHER_IP}" - exit - fi - fi - - if [[ "$DISABLEIP6" == "yes" ]]; then - echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}Yes${CL}" - elif [[ "$DISABLEIP6" == "no" ]]; then - echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}No${CL}" + fi + if [ ! -z "$GATE" ]; then + if [[ "$GATE" =~ $ip_regex ]]; then + echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}$GATE${CL}" + GATE=",gw=$GATE" else - msg_error "Disable IPv6 needs to be 'yes' or 'no'" - exit + msg_error "Invalid IP Address format for Gateway. Needs to be 0.0.0.0, was ${GATE}" + exit fi + else + msg_error "Gateway IP Address cannot be empty" + exit + fi - if [[ ! -z "$MTU" ]]; then - if [[ "$MTU" =~ ^-?[0-9]+$ ]]; then - echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU${CL}" - MTU=",mtu=$MTU" - else - msg_error "MTU must be an integer, was ${MTU}" - exit - fi + if [[ ! -z "$APT_CACHER_IP" ]]; then + if [[ "$APT_CACHER_IP" =~ $ip_regex ]]; then + APT_CACHER="yes" + echo -e "${NETWORK}${BOLD}${DGN}APT-CACHER IP Address: ${BGN}$APT_CACHER_IP${CL}" else - MTU="" - echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}" - + msg_error "Invalid IP Address format for APT-Cacher. Needs to be 0.0.0.0, was ${APT_CACHER_IP}" + exit fi + fi - if [[ ! -z "$SD" ]]; then - echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}$SD${CL}" - SD="-searchdomain=$SD" + if [[ "$DISABLEIP6" == "yes" ]]; then + echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}Yes${CL}" + elif [[ "$DISABLEIP6" == "no" ]]; then + echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}No${CL}" + else + msg_error "Disable IPv6 needs to be 'yes' or 'no'" + exit + fi + + if [[ ! -z "$MTU" ]]; then + if [[ "$MTU" =~ ^-?[0-9]+$ ]]; then + echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU${CL}" + MTU=",mtu=$MTU" else - SD="" - echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}HOST${CL}" + msg_error "MTU must be an integer, was ${MTU}" + exit fi + else + MTU="" + echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}" - if [[ ! -z "$NS" ]]; then - if [[ "$NS" =~ $ip_regex ]]; then - echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}$NS${CL}" - NS="-nameserver=$NS" - else - msg_error "Invalid IP Address format for DNS Server. Needs to be 0.0.0.0, was ${NS}" - exit - fi + fi + + if [[ ! -z "$SD" ]]; then + echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}$SD${CL}" + SD="-searchdomain=$SD" + else + SD="" + echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}HOST${CL}" + fi + + if [[ ! -z "$NS" ]]; then + if [[ "$NS" =~ $ip_regex ]]; then + echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}$NS${CL}" + NS="-nameserver=$NS" else - NS="" - echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}HOST${CL}" + msg_error "Invalid IP Address format for DNS Server. Needs to be 0.0.0.0, was ${NS}" + exit fi + else + NS="" + echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}HOST${CL}" + fi - if [[ ! -z "$MAC" ]]; then - if [[ "$MAC" =~ ^([A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}$ ]]; then - echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}" - MAC=",hwaddr=$MAC" - else - msg_error "MAC Address must be in the format xx:xx:xx:xx:xx:xx, was ${MAC}" - exit - fi - fi - - if [[ ! -z "$VLAN" ]]; then - if [[ "$VLAN" =~ ^-?[0-9]+$ ]]; then - echo -e "${VLANTAG}${BOLD}${DGN}Vlan: ${BGN}$VLAN${CL}" - VLAN=",tag=$VLAN" - else - msg_error "VLAN must be an integer, was ${VLAN}" - exit - fi - fi - - if [[ ! -z "$TAGS" ]]; then - echo -e "${NETWORK}${BOLD}${DGN}Tags: ${BGN}$TAGS${CL}" - fi - - if [[ "$SSH" == "yes" ]]; then - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - if [[ ! -z "$SSH_AUTHORIZED_KEY" ]]; then - echo -e "${ROOTSSH}${BOLD}${DGN}SSH Authorized Key: ${BGN}********************${CL}" - else - echo -e "${ROOTSSH}${BOLD}${DGN}SSH Authorized Key: ${BGN}None${CL}" - fi - elif [[ "$SSH" == "no" ]]; then - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" + if [[ ! -z "$MAC" ]]; then + if [[ "$MAC" =~ ^([A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}$ ]]; then + echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}" + MAC=",hwaddr=$MAC" else - msg_error "SSH needs to be 'yes' or 'no', was ${SSH}" - exit + msg_error "MAC Address must be in the format xx:xx:xx:xx:xx:xx, was ${MAC}" + exit fi + fi - if [[ "$VERB" == "yes" ]]; then - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERB${CL}" - elif [[ "$VERB" == "no" ]]; then - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}No${CL}" + if [[ ! -z "$VLAN" ]]; then + if [[ "$VLAN" =~ ^-?[0-9]+$ ]]; then + echo -e "${VLANTAG}${BOLD}${DGN}Vlan: ${BGN}$VLAN${CL}" + VLAN=",tag=$VLAN" else - msg_error "Verbose Mode needs to be 'yes' or 'no', was ${VERB}" - exit + msg_error "VLAN must be an integer, was ${VLAN}" + exit fi + fi - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS WITH CONFIG FILE COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above settings${CL}" + if [[ ! -z "$TAGS" ]]; then + echo -e "${NETWORK}${BOLD}${DGN}Tags: ${BGN}$TAGS${CL}" + fi + + if [[ "$SSH" == "yes" ]]; then + echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" + if [[ ! -z "$SSH_AUTHORIZED_KEY" ]]; then + echo -e "${ROOTSSH}${BOLD}${DGN}SSH Authorized Key: ${BGN}********************${CL}" else - clear - header_info - echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" - config_file + echo -e "${ROOTSSH}${BOLD}${DGN}SSH Authorized Key: ${BGN}None${CL}" fi + elif [[ "$SSH" == "no" ]]; then + echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" + else + msg_error "SSH needs to be 'yes' or 'no', was ${SSH}" + exit + fi + + if [[ "$VERB" == "yes" ]]; then + echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERB${CL}" + elif [[ "$VERB" == "no" ]]; then + echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}No${CL}" + else + msg_error "Verbose Mode needs to be 'yes' or 'no', was ${VERB}" + exit + fi + + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS WITH CONFIG FILE COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above settings${CL}" + else + clear + header_info + echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" + config_file + fi } install_script() { - pve_check - shell_check - root_check - arch_check - ssh_check - maxkeys_check - diagnostics_check + pve_check + shell_check + root_check + arch_check + ssh_check + maxkeys_check + diagnostics_check - if systemctl is-active -q ping-instances.service; then - systemctl -q stop ping-instances.service + if systemctl is-active -q ping-instances.service; then + systemctl -q stop ping-instances.service + fi + NEXTID=$(pvesh get /cluster/nextid) + timezone=$(cat /etc/timezone) + header_info + while true; do + + CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SETTINGS" --menu "Choose an option:" \ + 18 60 6 \ + "1" "Default Settings" \ + "2" "Default Settings (with verbose)" \ + "3" "Advanced Settings" \ + "4" "Use Config File" \ + "5" "Diagnostic Settings" \ + "6" "Exit" --nocancel --default-item "1" 3>&1 1>&2 2>&3) + + if [ $? -ne 0 ]; then + echo -e "${CROSS}${RD} Menu canceled. Exiting.${CL}" + exit 0 fi - NEXTID=$(pvesh get /cluster/nextid) - timezone=$(cat /etc/timezone) - header_info - while true; do - CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SETTINGS" --menu "Choose an option:" \ - 18 60 6 \ - "1" "Default Settings" \ - "2" "Default Settings (with verbose)" \ - "3" "Advanced Settings" \ - "4" "Use Config File" \ - "5" "Diagnostic Settings" \ - "6" "Exit" --nocancel --default-item "1" 3>&1 1>&2 2>&3) - - if [ $? -ne 0 ]; then - echo -e "${CROSS}${RD} Menu canceled. Exiting.${CL}" - exit 0 + case $CHOICE in + 1) + header_info + echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME${CL}" + VERB="no" + METHOD="default" + base_settings "$VERB" + echo_default + break + ;; + 2) + header_info + echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME (${VERBOSE_CROPPED}Verbose)${CL}" + VERB="yes" + METHOD="default" + base_settings "$VERB" + echo_default + break + ;; + 3) + header_info + echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" + METHOD="advanced" + base_settings + advanced_settings + break + ;; + 4) + header_info + echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" + METHOD="advanced" + base_settings + config_file + break + ;; + 5) + if [[ $DIAGNOSTICS == "yes" ]]; then + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ + --yes-button "No" --no-button "Back"; then + DIAGNOSTICS="no" + sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 fi + else + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ + --yes-button "Yes" --no-button "Back"; then + DIAGNOSTICS="yes" + sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 + fi + fi - case $CHOICE in - 1) - header_info - echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME${CL}" - VERB="no" - METHOD="default" - base_settings "$VERB" - echo_default - break - ;; - 2) - header_info - echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME (${VERBOSE_CROPPED}Verbose)${CL}" - VERB="yes" - METHOD="default" - base_settings "$VERB" - echo_default - break - ;; - 3) - header_info - echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" - METHOD="advanced" - base_settings - advanced_settings - break - ;; - 4) - header_info - echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" - METHOD="advanced" - base_settings - config_file - break - ;; - 5) - if [[ $DIAGNOSTICS == "yes" ]]; then - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ - --yes-button "No" --no-button "Back"; then - DIAGNOSTICS="no" - sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 - fi - else - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ - --yes-button "Yes" --no-button "Back"; then - DIAGNOSTICS="yes" - sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 - fi - fi - - ;; - 6) - echo -e "${CROSS}${RD}Exiting.${CL}" - exit 0 - ;; - *) - echo -e "${CROSS}${RD}Invalid option, please try again.${CL}" - ;; - esac - done + ;; + 6) + echo -e "${CROSS}${RD}Exiting.${CL}" + exit 0 + ;; + *) + echo -e "${CROSS}${RD}Invalid option, please try again.${CL}" + ;; + esac + done } check_container_resources() { - # Check actual RAM & Cores - current_ram=$(free -m | awk 'NR==2{print $2}') - current_cpu=$(nproc) + # Check actual RAM & Cores + current_ram=$(free -m | awk 'NR==2{print $2}') + current_cpu=$(nproc) - # Check whether the current RAM is less than the required RAM or the CPU cores are less than required - if [[ "$current_ram" -lt "$var_ram" ]] || [[ "$current_cpu" -lt "$var_cpu" ]]; then - echo -e "\n${INFO}${HOLD} ${GN}Required: ${var_cpu} CPU, ${var_ram}MB RAM ${CL}| ${RD}Current: ${current_cpu} CPU, ${current_ram}MB RAM${CL}" - echo -e "${YWB}Please ensure that the ${APP} LXC is configured with at least ${var_cpu} vCPU and ${var_ram} MB RAM for the build process.${CL}\n" - echo -ne "${INFO}${HOLD} May cause data loss! ${INFO} Continue update with under-provisioned LXC? " - read -r prompt - # Check if the input is 'yes', otherwise exit with status 1 - if [[ ! ${prompt,,} =~ ^(yes)$ ]]; then - echo -e "${CROSS}${HOLD} ${YWB}Exiting based on user input.${CL}" - exit 1 - fi - else - echo -e "" + # Check whether the current RAM is less than the required RAM or the CPU cores are less than required + if [[ "$current_ram" -lt "$var_ram" ]] || [[ "$current_cpu" -lt "$var_cpu" ]]; then + echo -e "\n${INFO}${HOLD} ${GN}Required: ${var_cpu} CPU, ${var_ram}MB RAM ${CL}| ${RD}Current: ${current_cpu} CPU, ${current_ram}MB RAM${CL}" + echo -e "${YWB}Please ensure that the ${APP} LXC is configured with at least ${var_cpu} vCPU and ${var_ram} MB RAM for the build process.${CL}\n" + echo -ne "${INFO}${HOLD} May cause data loss! ${INFO} Continue update with under-provisioned LXC? " + read -r prompt + # Check if the input is 'yes', otherwise exit with status 1 + if [[ ! ${prompt,,} =~ ^(yes)$ ]]; then + echo -e "${CROSS}${HOLD} ${YWB}Exiting based on user input.${CL}" + exit 1 fi + else + echo -e "" + fi } check_container_storage() { - # Check if the /boot partition is more than 80% full - total_size=$(df /boot --output=size | tail -n 1) - local used_size=$(df /boot --output=used | tail -n 1) - usage=$((100 * used_size / total_size)) - if ((usage > 80)); then - # Prompt the user for confirmation to continue - echo -e "${INFO}${HOLD} ${YWB}Warning: Storage is dangerously low (${usage}%).${CL}" - echo -ne "Continue anyway? " - read -r prompt - # Check if the input is 'y' or 'yes', otherwise exit with status 1 - if [[ ! ${prompt,,} =~ ^(y|yes)$ ]]; then - echo -e "${CROSS}${HOLD}${YWB}Exiting based on user input.${CL}" - exit 1 - fi + # Check if the /boot partition is more than 80% full + total_size=$(df /boot --output=size | tail -n 1) + local used_size=$(df /boot --output=used | tail -n 1) + usage=$((100 * used_size / total_size)) + if ((usage > 80)); then + # Prompt the user for confirmation to continue + echo -e "${INFO}${HOLD} ${YWB}Warning: Storage is dangerously low (${usage}%).${CL}" + echo -ne "Continue anyway? " + read -r prompt + # Check if the input is 'y' or 'yes', otherwise exit with status 1 + if [[ ! ${prompt,,} =~ ^(y|yes)$ ]]; then + echo -e "${CROSS}${HOLD}${YWB}Exiting based on user input.${CL}" + exit 1 fi + fi } start() { - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) - if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - exit_script - exit - fi - SPINNER_PID="" - install_script - else - CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC Update/Setting" --menu \ - "Support/Update functions for ${APP} LXC. Choose an option:" \ - 12 60 3 \ - "1" "YES (Silent Mode)" \ - "2" "YES (Verbose Mode)" \ - "3" "NO (Cancel Update)" --nocancel --default-item "1" 3>&1 1>&2 2>&3) - - case "$CHOICE" in - 1) - VERB="no" - set_std_mode - ;; - 2) - VERB="yes" - set_std_mode - ;; - 3) - clear - exit_script - exit - ;; - esac - - SPINNER_PID="" - update_script + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) + if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + exit_script + exit fi + SPINNER_PID="" + install_script + else + CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC Update/Setting" --menu \ + "Support/Update functions for ${APP} LXC. Choose an option:" \ + 12 60 3 \ + "1" "YES (Silent Mode)" \ + "2" "YES (Verbose Mode)" \ + "3" "NO (Cancel Update)" --nocancel --default-item "1" 3>&1 1>&2 2>&3) + + case "$CHOICE" in + 1) + VERB="no" + set_std_mode + ;; + 2) + VERB="yes" + set_std_mode + ;; + 3) + clear + exit_script + exit + ;; + esac + + SPINNER_PID="" + update_script + fi } # This function collects user settings and integrates all the collected information. build_container() { - # if [ "$VERB" == "yes" ]; then set -x; fi + # if [ "$VERB" == "yes" ]; then set -x; fi - if [ "$CT_TYPE" == "1" ]; then - FEATURES="keyctl=1,nesting=1" - else - FEATURES="nesting=1" - fi + if [ "$CT_TYPE" == "1" ]; then + FEATURES="keyctl=1,nesting=1" + else + FEATURES="nesting=1" + fi - if [[ $DIAGNOSTICS == "yes" ]]; then - post_to_api - fi + if [[ $DIAGNOSTICS == "yes" ]]; then + post_to_api + fi - TEMP_DIR=$(mktemp -d) - pushd "$TEMP_DIR" >/dev/null - if [ "$var_os" == "alpine" ]; then - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)" - else - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)" - fi - export RANDOM_UUID="$RANDOM_UUID" - export CACHER="$APT_CACHER" - export CACHER_IP="$APT_CACHER_IP" - export tz="$timezone" - export DISABLEIPV6="$DISABLEIP6" - export APPLICATION="$APP" - export app="$NSAPP" - export PASSWORD="$PW" - export VERBOSE="$VERB" - export SSH_ROOT="${SSH}" - export SSH_AUTHORIZED_KEY - export CTID="$CT_ID" - export CTTYPE="$CT_TYPE" - export PCT_OSTYPE="$var_os" - export PCT_OSVERSION="$var_version" - export PCT_DISK_SIZE="$DISK_SIZE" - export PCT_OPTIONS=" + TEMP_DIR=$(mktemp -d) + pushd "$TEMP_DIR" >/dev/null + if [ "$var_os" == "alpine" ]; then + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)" + else + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)" + fi + export RANDOM_UUID="$RANDOM_UUID" + export CACHER="$APT_CACHER" + export CACHER_IP="$APT_CACHER_IP" + export tz="$timezone" + export DISABLEIPV6="$DISABLEIP6" + export APPLICATION="$APP" + export app="$NSAPP" + export PASSWORD="$PW" + export VERBOSE="$VERB" + export SSH_ROOT="${SSH}" + export SSH_AUTHORIZED_KEY + export CTID="$CT_ID" + export CTTYPE="$CT_TYPE" + export PCT_OSTYPE="$var_os" + export PCT_OSVERSION="$var_version" + export PCT_DISK_SIZE="$DISK_SIZE" + export PCT_OPTIONS=" -features $FEATURES -hostname $HN -tags $TAGS @@ -1335,12 +1247,12 @@ build_container() { -unprivileged $CT_TYPE $PW " - # This executes create_lxc.sh and creates the container and .conf file - bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)" $? + # This executes create_lxc.sh and creates the container and .conf file + bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)" $? - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - if [ "$CT_TYPE" == "0" ]; then - cat <>"$LXC_CONFIG" + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + if [ "$CT_TYPE" == "0" ]; then + cat <>"$LXC_CONFIG" # USB passthrough lxc.cgroup2.devices.allow: a lxc.cap.drop: @@ -1352,11 +1264,11 @@ lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create= lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF - fi + fi - if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then - cat <>$LXC_CONFIG + if [ "$CT_TYPE" == "0" ]; then + if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then + cat <>$LXC_CONFIG # VAAPI hardware transcoding lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm @@ -1365,50 +1277,50 @@ lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file EOF - fi - else - if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then - if [[ -e "/dev/dri/renderD128" ]]; then - if [[ -e "/dev/dri/card0" ]]; then - cat <>$LXC_CONFIG + fi + else + if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then + if [[ -e "/dev/dri/renderD128" ]]; then + if [[ -e "/dev/dri/card0" ]]; then + cat <>$LXC_CONFIG # VAAPI hardware transcoding dev0: /dev/dri/card0,gid=44 dev1: /dev/dri/renderD128,gid=104 EOF - else - cat <>"$LXC_CONFIG" + else + cat <>"$LXC_CONFIG" # VAAPI hardware transcoding dev0: /dev/dri/card1,gid=44 dev1: /dev/dri/renderD128,gid=104 EOF - fi - fi fi + fi fi + fi - # This starts the container and executes -install.sh - msg_info "Starting LXC Container" - pct start "$CTID" - msg_ok "Started LXC Container" - if [ "$var_os" == "alpine" ]; then - sleep 3 - pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories + # This starts the container and executes -install.sh + msg_info "Starting LXC Container" + pct start "$CTID" + msg_ok "Started LXC Container" + if [ "$var_os" == "alpine" ]; then + sleep 3 + pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories http://dl-cdn.alpinelinux.org/alpine/latest-stable/main http://dl-cdn.alpinelinux.org/alpine/latest-stable/community EOF' - pct exec "$CTID" -- ash -c "apk add bash >/dev/null" - fi - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/install/"$var_install".sh)" $? + pct exec "$CTID" -- ash -c "apk add bash >/dev/null" + fi + lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/install/"$var_install".sh)" $? } # This function sets the description of the container. description() { - IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) + IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - # Generate LXC Description - DESCRIPTION=$( - cat < Logo @@ -1436,57 +1348,57 @@ description() { EOF - ) + ) - # Set Description in LXC - pct set "$CTID" -description "$DESCRIPTION" + # Set Description in LXC + pct set "$CTID" -description "$DESCRIPTION" - if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service - fi + if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service + fi - post_update_to_api "done" "none" + post_update_to_api "done" "none" } set_std_mode() { - if [ "$VERB" = "yes" ]; then - STD="" - else - STD="silent" - fi + if [ "$VERB" = "yes" ]; then + STD="" + else + STD="silent" + fi } # Silent execution function silent() { - if [ "$VERB" = "no" ]; then - "$@" >/dev/null 2>&1 || return 1 - else - "$@" || return 1 - fi + if [ "$VERB" = "no" ]; then + "$@" >/dev/null 2>&1 || return 1 + else + "$@" || return 1 + fi } api_exit_script() { - exit_code=$? # Capture the exit status of the last executed command - #200 exit codes indicate error in create_lxc.sh - #100 exit codes indicate error in install.func + exit_code=$? # Capture the exit status of the last executed command + #200 exit codes indicate error in create_lxc.sh + #100 exit codes indicate error in install.func - if [ $exit_code -ne 0 ]; then - case $exit_code in - 100) post_update_to_api "failed" "100: Unexpected error in create_lxc.sh" ;; - 101) post_update_to_api "failed" "101: No network connection detected in create_lxc.sh" ;; - 200) post_update_to_api "failed" "200: LXC creation failed in create_lxc.sh" ;; - 201) post_update_to_api "failed" "201: Invalid Storage class in create_lxc.sh" ;; - 202) post_update_to_api "failed" "202: User aborted menu in create_lxc.sh" ;; - 203) post_update_to_api "failed" "203: CTID not set in create_lxc.sh" ;; - 204) post_update_to_api "failed" "204: PCT_OSTYPE not set in create_lxc.sh" ;; - 205) post_update_to_api "failed" "205: CTID cannot be less than 100 in create_lxc.sh" ;; - 206) post_update_to_api "failed" "206: CTID already in use in create_lxc.sh" ;; - 207) post_update_to_api "failed" "207: Template not found in create_lxc.sh" ;; - 208) post_update_to_api "failed" "208: Error downloading template in create_lxc.sh" ;; - 209) post_update_to_api "failed" "209: Container creation failed, but template is intact in create_lxc.sh" ;; - *) post_update_to_api "failed" "Unknown error, exit code: $exit_code in create_lxc.sh" ;; - esac - fi + if [ $exit_code -ne 0 ]; then + case $exit_code in + 100) post_update_to_api "failed" "100: Unexpected error in create_lxc.sh" ;; + 101) post_update_to_api "failed" "101: No network connection detected in create_lxc.sh" ;; + 200) post_update_to_api "failed" "200: LXC creation failed in create_lxc.sh" ;; + 201) post_update_to_api "failed" "201: Invalid Storage class in create_lxc.sh" ;; + 202) post_update_to_api "failed" "202: User aborted menu in create_lxc.sh" ;; + 203) post_update_to_api "failed" "203: CTID not set in create_lxc.sh" ;; + 204) post_update_to_api "failed" "204: PCT_OSTYPE not set in create_lxc.sh" ;; + 205) post_update_to_api "failed" "205: CTID cannot be less than 100 in create_lxc.sh" ;; + 206) post_update_to_api "failed" "206: CTID already in use in create_lxc.sh" ;; + 207) post_update_to_api "failed" "207: Template not found in create_lxc.sh" ;; + 208) post_update_to_api "failed" "208: Error downloading template in create_lxc.sh" ;; + 209) post_update_to_api "failed" "209: Container creation failed, but template is intact in create_lxc.sh" ;; + *) post_update_to_api "failed" "Unknown error, exit code: $exit_code in create_lxc.sh" ;; + esac + fi } trap 'api_exit_script' EXIT From 408b16c5a50ffb35ee13c268d1a3fc85e5c690f1 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 13:01:32 +0200 Subject: [PATCH 177/463] testing --- misc/core.func | 28 +++++++++++++++++++++------- misc/create_lxc.sh | 6 +++--- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/misc/core.func b/misc/core.func index b1dda6d3..2b7780e6 100644 --- a/misc/core.func +++ b/misc/core.func @@ -250,6 +250,17 @@ header_info() { fi } +ensure_tput() { + if ! command -v tput >/dev/null 2>&1; then + if grep -qi 'alpine' /etc/os-release; then + apk add --no-cache ncurses >/dev/null 2>&1 + elif command -v apt-get >/dev/null 2>&1; then + apt-get update -qq >/dev/null + apt-get install -y -qq ncurses-bin >/dev/null 2>&1 + fi + fi +} + # ------------------------------------------------------------------------------ # Handles specific curl error codes and displays descriptive messages. # ------------------------------------------------------------------------------ @@ -302,6 +313,11 @@ spinner() { done } +clear_line() { + tput cr 2>/dev/null || echo -en "\r" + tput el 2>/dev/null || echo -en "\033[K" +} + stop_spinner() { local pid="${SPINNER_PID:-}" [[ -z "$pid" && -f /tmp/.spinner.pid ]] && pid=$(&2 - else - echo -e "${BFR:-} ${CM:-✔️} ${GN}${msg}${CL}" - fi + [[ -z "$msg" ]] && return + stop_spinner + clear_line + printf "%s %b\n" "$CM" "${GN}${msg}${CL}" >&2 + unset MSG_INFO_SHOWN["$msg"] } msg_error() { diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 98b4d68e..85d49e4a 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -73,7 +73,7 @@ if ! check_storage_support "vztmpl"; then msg_error "No valid storage found for 'vztmpl' (Template)." exit 1 fi -msg_ok "Storage types rootdir and vztmpl are supported." +msg_ok "Validated Storage (rootdir / vztmpl)." # This function is used to select the storage class and determine the corresponding storage content type and label. function select_storage() { @@ -153,7 +153,6 @@ function select_storage() { exit 202 } - # Validierung gegen STORAGE_MAP if [[ -z "$DISPLAY_SELECTED" || -z "${STORAGE_MAP[$DISPLAY_SELECTED]+_}" ]]; then whiptail --backtitle "Proxmox VE Helper Scripts" --title "Invalid Selection" \ --msgbox "No valid storage selected. Please choose a storage pool to continue." 9 60 @@ -298,6 +297,8 @@ if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE" || ! zstdcat "$TEMPLAT fi msg_ok "LXC Template '$TEMPLATE' is ready to use." + +msg_info "Creating LXC Container" # Check and fix subuid/subgid grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >>/etc/subuid grep -q "root:100000:65536" /etc/subgid || echo "root:100000:65536" >>/etc/subgid @@ -317,7 +318,6 @@ flock -w 60 9 || { exit 211 } -msg_info "Creating LXC Container" if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then msg_error "Container creation failed. Checking if template is corrupted or incomplete." From c4139b0657c12a7d3371eb2459b5d85906c3df3c Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 13:05:44 +0200 Subject: [PATCH 178/463] Update core.func --- misc/core.func | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/misc/core.func b/misc/core.func index 2b7780e6..f04abcb7 100644 --- a/misc/core.func +++ b/misc/core.func @@ -261,6 +261,27 @@ ensure_tput() { fi } +is_alpine() { + local os="${var_os:-$( + . /etc/os-release 2>/dev/null + echo "${ID:-}" + )}" + echo "[DEBUG] is_alpine(): OS='$os'" >&2 + [[ "$os" == "alpine" ]] +} + +is_verbose_mode() { + local verbose="${VERBOSE:-${var_verbose:-no}}" + local tty_status + if [[ -t 2 ]]; then + tty_status="interactive" + else + tty_status="not-a-tty" + fi + echo "[DEBUG] is_verbose_mode(): VERBOSE='$verbose', TTY=$tty_status" >&2 + [[ "$verbose" != "no" || ! -t 2 ]] +} + # ------------------------------------------------------------------------------ # Handles specific curl error codes and displays descriptive messages. # ------------------------------------------------------------------------------ @@ -348,7 +369,7 @@ msg_info() { stop_spinner SPINNER_MSG="$msg" - if [[ "${VERBOSE:-no}" != "no" || "${var_os:-}" == "alpine" || ! -t 2 ]]; then + if is_verbose_mode || is_alpine; then local HOURGLASS="${TAB}⏳${TAB}" printf "\r\e[2K%s %b" "$HOURGLASS" "${YW}${msg}${CL}" >&2 return From 03825ae872e62750ba57dbcad8873af009014dc5 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 13:23:40 +0200 Subject: [PATCH 179/463] Update core.func --- misc/core.func | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/misc/core.func b/misc/core.func index f04abcb7..8b1c07f1 100644 --- a/misc/core.func +++ b/misc/core.func @@ -262,12 +262,8 @@ ensure_tput() { } is_alpine() { - local os="${var_os:-$( - . /etc/os-release 2>/dev/null - echo "${ID:-}" - )}" - echo "[DEBUG] is_alpine(): OS='$os'" >&2 - [[ "$os" == "alpine" ]] + echo "[DEBUG] is_alpine(): var_os='${var_os:-}'" >&2 + [[ "${var_os:-}" == "alpine" ]] } is_verbose_mode() { From 77c70c5d1b795b55e8cf299764d794352528cd04 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 13:27:30 +0200 Subject: [PATCH 180/463] Update core.func --- misc/core.func | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/misc/core.func b/misc/core.func index 8b1c07f1..4442f809 100644 --- a/misc/core.func +++ b/misc/core.func @@ -262,8 +262,20 @@ ensure_tput() { } is_alpine() { - echo "[DEBUG] is_alpine(): var_os='${var_os:-}'" >&2 - [[ "${var_os:-}" == "alpine" ]] + local os_id="${var_os:-}" + + if [[ -z "$os_id" ]]; then + if [[ -f /etc/os-release ]]; then + os_id="$( + . /etc/os-release 2>/dev/null + echo "${ID:-}" + )" + fi + fi + + echo "[DEBUG] is_alpine(): os_id='${os_id}'" >&2 + + [[ "$os_id" == "alpine" ]] } is_verbose_mode() { From 4653230489d8daf94b2c270cd15f832decb6b24a Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 13:29:23 +0200 Subject: [PATCH 181/463] Update debian-install.sh --- install/debian-install.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/install/debian-install.sh b/install/debian-install.sh index a684ac06..fcca74fc 100644 --- a/install/debian-install.sh +++ b/install/debian-install.sh @@ -17,6 +17,8 @@ msg_info "Installing Dependencies" $STD apt-get install -y gpg msg_ok "Installed Dependencies" +setup_mariadb + #FFMPEG_VERSION="n7.1.1" FFMPEG_TYPE="full" setup_ffmpeg #fetch_and_deploy_gh_release "argus" "release-argus/Argus" "singlefile" "latest" "/opt/argus" "Argus-.*linux-amd64" @@ -31,7 +33,7 @@ msg_ok "Installed Dependencies" #NODE_MODULE="pnpm@10.1,yarn" #RELEASE=$(curl_handler -fsSL https://api.github.com/repos/babybuddy/babybuddy/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') #msg_ok "Get Release $RELEASE" -NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs +#NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs #PG_VERSION="16" setup_postgresql From 83915c116860452aef42097146189944baa8fbf7 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 13:30:41 +0200 Subject: [PATCH 182/463] Update tools.func --- misc/tools.func | 48 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 1793ce45..504a8f09 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -235,8 +235,14 @@ setup_mariadb() { DISTRO_CODENAME="$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)" CURRENT_OS="$(awk -F= '/^ID=/{print $2}' /etc/os-release)" - msg_info "Setting up MariaDB $MARIADB_VERSION" - # grab dynamic latest LTS version + msg_info "Preparing MariaDB $MARIADB_VERSION" + + if ! curl -fsI http://mirror.mariadb.org/repo/ >/dev/null; then + msg_error "MariaDB mirror not reachable" + return 1 + fi + msg_ok "MariaDB mirror reachable" + if [[ "$MARIADB_VERSION" == "latest" ]]; then MARIADB_VERSION=$(curl -fsSL http://mirror.mariadb.org/repo/ | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+/' | @@ -245,9 +251,10 @@ setup_mariadb() { sort -Vr | head -n1) if [[ -z "$MARIADB_VERSION" ]]; then - msg_error "Could not determine latest GA MariaDB version" + msg_error "Failed to detect latest MariaDB version" return 1 fi + msg_ok "Latest version is $MARIADB_VERSION" fi local CURRENT_VERSION="" @@ -256,32 +263,45 @@ setup_mariadb() { fi if [[ "$CURRENT_VERSION" == "$MARIADB_VERSION" ]]; then - $STD msg_info "MariaDB $MARIADB_VERSION, upgrading" + msg_info "MariaDB $MARIADB_VERSION already present, updating if needed" $STD apt-get update $STD apt-get install --only-upgrade -y mariadb-server mariadb-client - $STD msg_ok "MariaDB upgraded to $MARIADB_VERSION" + msg_ok "MariaDB already up to date" return 0 fi if [[ -n "$CURRENT_VERSION" ]]; then - $STD msg_info "Upgrading MariaDB $CURRENT_VERSION to $MARIADB_VERSION" - $STD systemctl stop mariadb >/dev/null 2>&1 || true + msg_info "Removing MariaDB $CURRENT_VERSION" + systemctl stop mariadb >/dev/null 2>&1 || true $STD apt-get purge -y 'mariadb*' || true rm -f /etc/apt/sources.list.d/mariadb.list /etc/apt/trusted.gpg.d/mariadb.gpg - else - $STD msg_info "Setup MariaDB $MARIADB_VERSION" fi - curl -fsSL "https://mariadb.org/mariadb_release_signing_key.asc" | - gpg --dearmor -o /etc/apt/trusted.gpg.d/mariadb.gpg + if curl -fsSL "https://mariadb.org/mariadb_release_signing_key.asc" | + gpg --dearmor -o /etc/apt/trusted.gpg.d/mariadb.gpg; then + msg_ok "GPG key imported" + else + msg_error "Failed to import GPG key" + return 1 + fi echo "deb [signed-by=/etc/apt/trusted.gpg.d/mariadb.gpg] http://mirror.mariadb.org/repo/${MARIADB_VERSION}/${CURRENT_OS} ${DISTRO_CODENAME} main" \ >/etc/apt/sources.list.d/mariadb.list + msg_ok "Repository configured" - $STD apt-get update - $STD apt-get install -y mariadb-server mariadb-client + if $STD apt-get update; then + msg_ok "APT index updated" + else + msg_error "APT update failed" + return 1 + fi - msg_ok "Setup MariaDB $MARIADB_VERSION" + if $STD apt-get install -y mariadb-server mariadb-client; then + msg_ok "MariaDB $MARIADB_VERSION installed" + else + msg_error "MariaDB installation failed" + return 1 + fi } # ------------------------------------------------------------------------------ From 6a28e4c09e20d0c42a5029fd40bc850574e614f1 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 13:34:35 +0200 Subject: [PATCH 183/463] Update core.func --- misc/core.func | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/misc/core.func b/misc/core.func index 4442f809..42964889 100644 --- a/misc/core.func +++ b/misc/core.func @@ -262,19 +262,16 @@ ensure_tput() { } is_alpine() { - local os_id="${var_os:-}" + local os_id="${var_os:-${PCT_OSTYPE:-}}" - if [[ -z "$os_id" ]]; then - if [[ -f /etc/os-release ]]; then - os_id="$( - . /etc/os-release 2>/dev/null - echo "${ID:-}" - )" - fi + if [[ -z "$os_id" && -f /etc/os-release ]]; then + os_id="$( + . /etc/os-release 2>/dev/null + echo "${ID:-}" + )" fi - echo "[DEBUG] is_alpine(): os_id='${os_id}'" >&2 - + [[ "${DEBUG:-}" == "true" ]] && echo "[DEBUG] is_alpine(): os_id='${os_id}'" >&2 [[ "$os_id" == "alpine" ]] } From 021d645de4f785c77930b946cfc7da482fbea870 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 13:38:25 +0200 Subject: [PATCH 184/463] Update core.func --- misc/core.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/core.func b/misc/core.func index 42964889..8fabfd77 100644 --- a/misc/core.func +++ b/misc/core.func @@ -271,7 +271,7 @@ is_alpine() { )" fi - [[ "${DEBUG:-}" == "true" ]] && echo "[DEBUG] is_alpine(): os_id='${os_id}'" >&2 + echo "[DEBUG] is_alpine(): os_id='${os_id}'" >&2 [[ "$os_id" == "alpine" ]] } From d18f82a36ec2ff81ab5c52980603671d40e42591 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 13:39:45 +0200 Subject: [PATCH 185/463] Update core.func --- misc/core.func | 2 -- 1 file changed, 2 deletions(-) diff --git a/misc/core.func b/misc/core.func index 8fabfd77..e313ea18 100644 --- a/misc/core.func +++ b/misc/core.func @@ -271,7 +271,6 @@ is_alpine() { )" fi - echo "[DEBUG] is_alpine(): os_id='${os_id}'" >&2 [[ "$os_id" == "alpine" ]] } @@ -283,7 +282,6 @@ is_verbose_mode() { else tty_status="not-a-tty" fi - echo "[DEBUG] is_verbose_mode(): VERBOSE='$verbose', TTY=$tty_status" >&2 [[ "$verbose" != "no" || ! -t 2 ]] } From 742f8dcb8f1fc8a103978b387754f1760bb113fe Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 13:43:28 +0200 Subject: [PATCH 186/463] Update tools.func --- misc/tools.func | 43 ++++++++++++++----------------------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 504a8f09..0ed2eca2 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -235,14 +235,13 @@ setup_mariadb() { DISTRO_CODENAME="$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)" CURRENT_OS="$(awk -F= '/^ID=/{print $2}' /etc/os-release)" - msg_info "Preparing MariaDB $MARIADB_VERSION" - if ! curl -fsI http://mirror.mariadb.org/repo/ >/dev/null; then msg_error "MariaDB mirror not reachable" return 1 fi - msg_ok "MariaDB mirror reachable" + msg_info "Setting up MariaDB $MARIADB_VERSION" + # grab dynamic latest LTS version if [[ "$MARIADB_VERSION" == "latest" ]]; then MARIADB_VERSION=$(curl -fsSL http://mirror.mariadb.org/repo/ | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+/' | @@ -251,10 +250,9 @@ setup_mariadb() { sort -Vr | head -n1) if [[ -z "$MARIADB_VERSION" ]]; then - msg_error "Failed to detect latest MariaDB version" + msg_error "Could not determine latest GA MariaDB version" return 1 fi - msg_ok "Latest version is $MARIADB_VERSION" fi local CURRENT_VERSION="" @@ -263,45 +261,32 @@ setup_mariadb() { fi if [[ "$CURRENT_VERSION" == "$MARIADB_VERSION" ]]; then - msg_info "MariaDB $MARIADB_VERSION already present, updating if needed" + $STD msg_info "MariaDB $MARIADB_VERSION, upgrading" $STD apt-get update $STD apt-get install --only-upgrade -y mariadb-server mariadb-client - msg_ok "MariaDB already up to date" + $STD msg_ok "MariaDB upgraded to $MARIADB_VERSION" return 0 fi if [[ -n "$CURRENT_VERSION" ]]; then - msg_info "Removing MariaDB $CURRENT_VERSION" - systemctl stop mariadb >/dev/null 2>&1 || true + $STD msg_info "Upgrading MariaDB $CURRENT_VERSION to $MARIADB_VERSION" + $STD systemctl stop mariadb >/dev/null 2>&1 || true $STD apt-get purge -y 'mariadb*' || true rm -f /etc/apt/sources.list.d/mariadb.list /etc/apt/trusted.gpg.d/mariadb.gpg + else + $STD msg_info "Setup MariaDB $MARIADB_VERSION" fi - if curl -fsSL "https://mariadb.org/mariadb_release_signing_key.asc" | - gpg --dearmor -o /etc/apt/trusted.gpg.d/mariadb.gpg; then - msg_ok "GPG key imported" - else - msg_error "Failed to import GPG key" - return 1 - fi + curl -fsSL "https://mariadb.org/mariadb_release_signing_key.asc" | + gpg --dearmor -o /etc/apt/trusted.gpg.d/mariadb.gpg echo "deb [signed-by=/etc/apt/trusted.gpg.d/mariadb.gpg] http://mirror.mariadb.org/repo/${MARIADB_VERSION}/${CURRENT_OS} ${DISTRO_CODENAME} main" \ >/etc/apt/sources.list.d/mariadb.list - msg_ok "Repository configured" - if $STD apt-get update; then - msg_ok "APT index updated" - else - msg_error "APT update failed" - return 1 - fi + $STD apt-get update + $STD apt-get install -y mariadb-server mariadb-client - if $STD apt-get install -y mariadb-server mariadb-client; then - msg_ok "MariaDB $MARIADB_VERSION installed" - else - msg_error "MariaDB installation failed" - return 1 - fi + msg_ok "Setup MariaDB $MARIADB_VERSION" } # ------------------------------------------------------------------------------ From e3454e1e3724327de90852bdebd23ce914e41604 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 14:35:01 +0200 Subject: [PATCH 187/463] Update create_lxc.sh --- misc/create_lxc.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 85d49e4a..c801fafe 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -148,10 +148,12 @@ function select_storage() { while true; do DISPLAY_SELECTED=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ - 16 "$WIDTH" 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || { + 16 "$WIDTH" 6 "${MENU[@]}" 3>&1 1>&2 2>&3) + + if [[ $? -ne 0 ]]; then msg_error "Storage selection cancelled by user." exit 202 - } + fi if [[ -z "$DISPLAY_SELECTED" || -z "${STORAGE_MAP[$DISPLAY_SELECTED]+_}" ]]; then whiptail --backtitle "Proxmox VE Helper Scripts" --title "Invalid Selection" \ From 1371e841707e8e0f3ba847a5265067c985f65459 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Fri, 4 Jul 2025 12:39:26 +0000 Subject: [PATCH 188/463] Update versions.json (#680) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 94 +++++++++++++++--------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index b67df43b..96b66409 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,44 @@ [ + { + "name": "Graylog2/graylog2-server", + "version": "6.3.1", + "date": "2025-07-04T11:20:48Z" + }, + { + "name": "mattermost/mattermost", + "version": "preview-v0.1", + "date": "2025-06-27T14:35:47Z" + }, + { + "name": "theonedev/onedev", + "version": "v11.11.3", + "date": "2025-07-04T09:04:46Z" + }, + { + "name": "nzbgetcom/nzbget", + "version": "v25.2", + "date": "2025-07-04T08:21:42Z" + }, + { + "name": "bunkerity/bunkerweb", + "version": "v1.6.2", + "date": "2025-07-04T08:43:44Z" + }, + { + "name": "Checkmk/checkmk", + "version": "v2.2.0p44", + "date": "2025-07-04T06:44:06Z" + }, + { + "name": "redis/redis", + "version": "8.2-rc1-int", + "date": "2025-07-02T19:27:08Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2117", + "date": "2025-07-04T05:56:05Z" + }, { "name": "hyperion-project/hyperion.ng", "version": "2.1.1", @@ -19,6 +59,11 @@ "version": "15.2", "date": "2025-04-14T15:37:12Z" }, + { + "name": "keycloak/keycloak", + "version": "26.3.0", + "date": "2025-07-02T12:26:44Z" + }, { "name": "cloudflare/cloudflared", "version": "2025.7.0", @@ -29,16 +74,6 @@ "version": "v4.1.2", "date": "2025-07-03T16:59:29Z" }, - { - "name": "bunkerity/bunkerweb", - "version": "testing", - "date": "2025-07-03T16:52:55Z" - }, - { - "name": "Checkmk/checkmk", - "version": "v2.4.0p6", - "date": "2025-07-03T16:40:42Z" - }, { "name": "influxdata/influxdb", "version": "v3.2.1", @@ -64,16 +99,6 @@ "version": "fumadocs-openapi@9.0.17", "date": "2025-07-03T06:57:48Z" }, - { - "name": "mattermost/mattermost", - "version": "preview-v0.1", - "date": "2025-06-27T14:35:47Z" - }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2111", - "date": "2025-07-03T05:50:31Z" - }, { "name": "esphome/esphome", "version": "2025.6.3", @@ -114,16 +139,6 @@ "version": "2.5.1", "date": "2025-07-02T19:38:06Z" }, - { - "name": "redis/redis", - "version": "8.2-rc1-int", - "date": "2025-07-02T19:27:08Z" - }, - { - "name": "keycloak/keycloak", - "version": "26.3.0", - "date": "2025-07-02T12:26:44Z" - }, { "name": "ollama/ollama", "version": "v0.9.5", @@ -139,16 +154,6 @@ "version": "2025.7.0", "date": "2025-07-02T16:23:42Z" }, - { - "name": "nzbgetcom/nzbget", - "version": "v25.1", - "date": "2025-06-27T09:14:14Z" - }, - { - "name": "Graylog2/graylog2-server", - "version": "6.2.5", - "date": "2025-07-02T13:06:30Z" - }, { "name": "wazuh/wazuh", "version": "coverity-w27-4.13.0", @@ -284,11 +289,6 @@ "version": "0.50.5", "date": "2025-06-29T08:54:47Z" }, - { - "name": "theonedev/onedev", - "version": "v11.11.2", - "date": "2025-06-29T01:40:39Z" - }, { "name": "linkwarden/linkwarden", "version": "v2.11.2", @@ -436,8 +436,8 @@ }, { "name": "runtipi/runtipi", - "version": "v4.2.1", - "date": "2025-06-03T20:04:28Z" + "version": "nightly", + "date": "2025-06-23T19:10:33Z" }, { "name": "VictoriaMetrics/VictoriaMetrics", From af1c45ce14879685b4808b9df020bb09f76d8d5a Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 14:39:30 +0200 Subject: [PATCH 189/463] Update create_lxc.sh --- misc/create_lxc.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index c801fafe..f984269f 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -128,7 +128,7 @@ function select_storage() { local USED_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$USED") local FREE_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$FREE") local INFO="Free: ${FREE_FMT}B Used: ${USED_FMT}B" - STORAGE_MAP["$DISPLAY"]="$TAG" # Map DISPLAY to actual TAG + STORAGE_MAP["$DISPLAY"]="$TAG" MENU+=("$DISPLAY" "$INFO" "OFF") ((${#DISPLAY} > COL_WIDTH)) && COL_WIDTH=${#DISPLAY} done < <(pvesm status -content "$CONTENT" | awk 'NR>1') @@ -150,7 +150,8 @@ function select_storage() { "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ 16 "$WIDTH" 6 "${MENU[@]}" 3>&1 1>&2 2>&3) - if [[ $? -ne 0 ]]; then + local ret=$? + if [[ $ret -ne 0 ]]; then msg_error "Storage selection cancelled by user." exit 202 fi @@ -161,11 +162,9 @@ function select_storage() { continue fi - break + echo "${STORAGE_MAP[$DISPLAY_SELECTED]}" + return done - - echo "${STORAGE_MAP["$DISPLAY_SELECTED"]}" - } # Test if required variables are set From 4012dd3dcd85d86066dce11b8c014c7bbb5b8116 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 14:45:01 +0200 Subject: [PATCH 190/463] Update create_lxc.sh --- misc/create_lxc.sh | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index f984269f..7a10a916 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -146,24 +146,28 @@ function select_storage() { local WIDTH=$((COL_WIDTH + 42)) local DISPLAY_SELECTED="" while true; do - DISPLAY_SELECTED=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ + DISPLAY_SELECTED=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ + --title "Storage Pools" \ + --radiolist "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ 16 "$WIDTH" 6 "${MENU[@]}" 3>&1 1>&2 2>&3) - local ret=$? - if [[ $ret -ne 0 ]]; then + local exit_code=$? + if [ $exit_code -ne 0 ]; then msg_error "Storage selection cancelled by user." exit 202 fi - if [[ -z "$DISPLAY_SELECTED" || -z "${STORAGE_MAP[$DISPLAY_SELECTED]+_}" ]]; then - whiptail --backtitle "Proxmox VE Helper Scripts" --title "Invalid Selection" \ - --msgbox "No valid storage selected. Please choose a storage pool to continue." 9 60 + if [ -z "$DISPLAY_SELECTED" ]; then + whiptail --msgbox "You must select a storage pool to continue." 8 58 continue fi - echo "${STORAGE_MAP[$DISPLAY_SELECTED]}" - return + if [[ -n "${STORAGE_MAP[$DISPLAY_SELECTED]:-}" ]]; then + echo "${STORAGE_MAP[$DISPLAY_SELECTED]}" + return + else + whiptail --msgbox "Invalid selection. Please try again." 8 58 + fi done } From e7601162725b19337954b1cd867f59a07921fa70 Mon Sep 17 00:00:00 2001 From: Tobias <96661824+CrazyWolf13@users.noreply.github.com> Date: Fri, 4 Jul 2025 14:45:58 +0200 Subject: [PATCH 191/463] Create vikunja.json --- frontend/public/json/vikunja.json | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 frontend/public/json/vikunja.json diff --git a/frontend/public/json/vikunja.json b/frontend/public/json/vikunja.json new file mode 100644 index 00000000..ea171140 --- /dev/null +++ b/frontend/public/json/vikunja.json @@ -0,0 +1,35 @@ +{ + "name": "Vikunja", + "slug": "vikunja", + "categories": [ + 12 + ], + "date_created": "2024-11-05", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 3456, + "documentation": null, + "website": "https://vikunja.io/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/vikunja.webp", + "config_path": "/etc/vikunja/config.yml", + "description": "Vikunja is a powerful self-hosted todo app. It allows you to create and manage to-do lists. You can plan tasks, set priorities and collaborate with others. The best part is that your data is safe with you and you can customize the app to your liking. It's like a personal assistant that helps you stay organized.", + "install_methods": [ + { + "type": "default", + "script": "ct/vikunja.sh", + "resources": { + "cpu": 1, + "ram": 1024, + "hdd": 4, + "os": "debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} From cb1df6ff67418a6623b9642c35ff32b26821cee1 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 14:49:36 +0200 Subject: [PATCH 192/463] Update create_lxc.sh --- misc/create_lxc.sh | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 7a10a916..1664e094 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -211,26 +211,23 @@ if [[ -f "$DEFAULT_FILE" ]]; then else # TEMPLATE STORAGE SELECTION # Template Storage - if ! TEMPLATE_STORAGE=$(select_storage template); then - [[ $? -eq 202 ]] && { - msg_error "Template Storage selection cancelled by user. Exiting." - kill -INT $$ - } - msg_error "Unexpected error during template storage selection." - exit 1 - fi - msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage." + while true; do + TEMPLATE_STORAGE=$(select_storage template) + if [[ -n "$TEMPLATE_STORAGE" ]]; then + msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage." + break + fi + msg_warn "No valid template storage selected. Please try again." + done - # Container Storage - if ! CONTAINER_STORAGE=$(select_storage container); then - [[ $? -eq 202 ]] && { - msg_error "Container Storage selection cancelled by user. Exiting." - kill -INT $$ - } - msg_error "Unexpected error during container storage selection." - exit 1 - fi - msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage." + while true; do + CONTAINER_STORAGE=$(select_storage container) + if [[ -n "$CONTAINER_STORAGE" ]]; then + msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage." + break + fi + msg_warn "No valid container storage selected. Please try again." + done fi From 607ee1c468453821a963ddee470d09f46f330020 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Jul 2025 14:54:47 +0200 Subject: [PATCH 193/463] Update create_lxc.sh --- misc/create_lxc.sh | 123 ++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 63 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 1664e094..2b48093c 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -78,6 +78,7 @@ msg_ok "Validated Storage (rootdir / vztmpl)." # This function is used to select the storage class and determine the corresponding storage content type and label. function select_storage() { local CLASS=$1 CONTENT CONTENT_LABEL + case $CLASS in container) CONTENT='rootdir' @@ -104,22 +105,13 @@ function select_storage() { CONTENT_LABEL='Snippets' ;; *) - msg_error "Invalid storage class '$CLASS'." - exit 201 + msg_error "Invalid storage class '$CLASS'" + return 1 ;; esac - command -v whiptail >/dev/null || { - msg_error "whiptail missing." - exit 220 - } - command -v numfmt >/dev/null || { - msg_error "numfmt missing." - exit 221 - } - local -a MENU - local -A STORAGE_MAP=() + local -A STORAGE_MAP local COL_WIDTH=0 while read -r TAG TYPE _ TOTAL USED FREE _; do @@ -135,39 +127,30 @@ function select_storage() { if [ ${#MENU[@]} -eq 0 ]; then msg_error "No storage found for content type '$CONTENT'." - exit 203 + return 2 fi if [ $((${#MENU[@]} / 3)) -eq 1 ]; then - echo "${STORAGE_MAP[${MENU[0]}]}" - return + STORAGE_RESULT="${STORAGE_MAP[${MENU[0]}]}" + return 0 fi local WIDTH=$((COL_WIDTH + 42)) - local DISPLAY_SELECTED="" while true; do - DISPLAY_SELECTED=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ + local DISPLAY_SELECTED=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ --title "Storage Pools" \ --radiolist "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \ 16 "$WIDTH" 6 "${MENU[@]}" 3>&1 1>&2 2>&3) - local exit_code=$? - if [ $exit_code -ne 0 ]; then - msg_error "Storage selection cancelled by user." - exit 202 - fi + [[ $? -ne 0 ]] && return 3 - if [ -z "$DISPLAY_SELECTED" ]; then - whiptail --msgbox "You must select a storage pool to continue." 8 58 + if [[ -z "$DISPLAY_SELECTED" || -z "${STORAGE_MAP[$DISPLAY_SELECTED]+_}" ]]; then + whiptail --msgbox "No valid storage selected. Please try again." 8 58 continue fi - if [[ -n "${STORAGE_MAP[$DISPLAY_SELECTED]:-}" ]]; then - echo "${STORAGE_MAP[$DISPLAY_SELECTED]}" - return - else - whiptail --msgbox "Invalid selection. Please try again." 8 58 - fi + STORAGE_RESULT="${STORAGE_MAP[$DISPLAY_SELECTED]}" + return 0 done } @@ -195,41 +178,55 @@ if qm status "$CTID" &>/dev/null || pct status "$CTID" &>/dev/null; then exit 206 fi -DEFAULT_FILE="/usr/local/community-scripts/default_storage" -if [[ -f "$DEFAULT_FILE" ]]; then - source "$DEFAULT_FILE" - if [[ -n "$TEMPLATE_STORAGE" && -n "$CONTAINER_STORAGE" ]]; then - msg_info "Using default storage configuration from: $DEFAULT_FILE" - msg_ok "Template Storage: ${BL}$TEMPLATE_STORAGE${CL} ${GN}|${CL} Container Storage: ${BL}$CONTAINER_STORAGE${CL}" - else - msg_warn "Default storage file exists but is incomplete – falling back to manual selection" - TEMPLATE_STORAGE=$(select_storage template) - msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage." - CONTAINER_STORAGE=$(select_storage container) - msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage." +# DEFAULT_FILE="/usr/local/community-scripts/default_storage" +# if [[ -f "$DEFAULT_FILE" ]]; then +# source "$DEFAULT_FILE" +# if [[ -n "$TEMPLATE_STORAGE" && -n "$CONTAINER_STORAGE" ]]; then +# msg_info "Using default storage configuration from: $DEFAULT_FILE" +# msg_ok "Template Storage: ${BL}$TEMPLATE_STORAGE${CL} ${GN}|${CL} Container Storage: ${BL}$CONTAINER_STORAGE${CL}" +# else +# msg_warn "Default storage file exists but is incomplete – falling back to manual selection" +# TEMPLATE_STORAGE=$(select_storage template) +# msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage." +# CONTAINER_STORAGE=$(select_storage container) +# msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage." +# fi +# else +# # TEMPLATE STORAGE SELECTION +# # Template Storage +# while true; do +# TEMPLATE_STORAGE=$(select_storage template) +# if [[ -n "$TEMPLATE_STORAGE" ]]; then +# msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage." +# break +# fi +# msg_warn "No valid template storage selected. Please try again." +# done + +# while true; do +# CONTAINER_STORAGE=$(select_storage container) +# if [[ -n "$CONTAINER_STORAGE" ]]; then +# msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage." +# break +# fi +# msg_warn "No valid container storage selected. Please try again." +# done + +# fi + +while true; do + if select_storage template; then + TEMPLATE_STORAGE="$STORAGE_RESULT" + break fi -else - # TEMPLATE STORAGE SELECTION - # Template Storage - while true; do - TEMPLATE_STORAGE=$(select_storage template) - if [[ -n "$TEMPLATE_STORAGE" ]]; then - msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage." - break - fi - msg_warn "No valid template storage selected. Please try again." - done +done - while true; do - CONTAINER_STORAGE=$(select_storage container) - if [[ -n "$CONTAINER_STORAGE" ]]; then - msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage." - break - fi - msg_warn "No valid container storage selected. Please try again." - done - -fi +while true; do + if select_storage container; then + CONTAINER_STORAGE="$STORAGE_RESULT" + break + fi +done # Check free space on selected container storage STORAGE_FREE=$(pvesm status | awk -v s="$CONTAINER_STORAGE" '$1 == s { print $6 }') From 5cf6733c3abcc4fb9f3b6f9668633b1bf61c3192 Mon Sep 17 00:00:00 2001 From: Tobias <96661824+CrazyWolf13@users.noreply.github.com> Date: Fri, 4 Jul 2025 14:59:12 +0200 Subject: [PATCH 194/463] Update vikunja.sh --- ct/vikunja.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/vikunja.sh b/ct/vikunja.sh index 38d014d8..792e3b1e 100644 --- a/ct/vikunja.sh +++ b/ct/vikunja.sh @@ -49,6 +49,7 @@ function update_script() { msg_info "Updating ${APP} to ${RELEASE}" cd /opt rm -rf /opt/vikunja/vikunja + rm -rf "/opt/$FILENAME" curl -fsSL "https://dl.vikunja.io/vikunja/$RELEASE/$FILENAME" -o $(basename "https://dl.vikunja.io/vikunja/$RELEASE/$FILENAME") export DEBIAN_FRONTEND=noninteractive $STD dpkg -i $FILENAME From a79184eb8379630720c3c85e6d176705882c2c8f Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Fri, 4 Jul 2025 12:59:39 +0000 Subject: [PATCH 195/463] Update .app files (#681) Co-authored-by: GitHub Actions --- ct/headers/alpine-komodo | 6 ++++++ ct/headers/alpine-tinyauth | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 ct/headers/alpine-komodo create mode 100644 ct/headers/alpine-tinyauth diff --git a/ct/headers/alpine-komodo b/ct/headers/alpine-komodo new file mode 100644 index 00000000..b945cc1b --- /dev/null +++ b/ct/headers/alpine-komodo @@ -0,0 +1,6 @@ + ___ __ _ __ __ __ + / | / /___ (_)___ ___ / //_/___ ____ ___ ____ ____/ /___ + / /| | / / __ \/ / __ \/ _ \______/ ,< / __ \/ __ `__ \/ __ \/ __ / __ \ + / ___ |/ / /_/ / / / / / __/_____/ /| / /_/ / / / / / / /_/ / /_/ / /_/ / +/_/ |_/_/ .___/_/_/ /_/\___/ /_/ |_\____/_/ /_/ /_/\____/\__,_/\____/ + /_/ diff --git a/ct/headers/alpine-tinyauth b/ct/headers/alpine-tinyauth new file mode 100644 index 00000000..9fff055f --- /dev/null +++ b/ct/headers/alpine-tinyauth @@ -0,0 +1,6 @@ + ___ __ _ _______ __ __ + / | / /___ (_)___ ___ /_ __(_)___ __ ______ ___ __/ /_/ /_ + / /| | / / __ \/ / __ \/ _ \______/ / / / __ \/ / / / __ `/ / / / __/ __ \ + / ___ |/ / /_/ / / / / / __/_____/ / / / / / / /_/ / /_/ / /_/ / /_/ / / / +/_/ |_/_/ .___/_/_/ /_/\___/ /_/ /_/_/ /_/\__, /\__,_/\__,_/\__/_/ /_/ + /_/ /____/ From 04ff0917f35494056c324700784bc429bf96ca1b Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Sat, 5 Jul 2025 01:27:42 +0000 Subject: [PATCH 196/463] Update versions.json (#682) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 100 ++++++++++++----------------- 1 file changed, 40 insertions(+), 60 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 96b66409..7bf1e201 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,44 @@ [ + { + "name": "steveiliop56/tinyauth", + "version": "v3.4.1", + "date": "2025-06-11T07:53:44Z" + }, + { + "name": "cross-seed/cross-seed", + "version": "v6.12.7", + "date": "2025-06-18T03:44:24Z" + }, + { + "name": "home-assistant/core", + "version": "2025.7.1", + "date": "2025-07-04T20:02:52Z" + }, + { + "name": "Luligu/matterbridge", + "version": "3.1.1", + "date": "2025-07-04T19:50:37Z" + }, + { + "name": "homarr-labs/homarr", + "version": "v1.27.0", + "date": "2025-07-04T19:16:16Z" + }, + { + "name": "zitadel/zitadel", + "version": "v3.3.0", + "date": "2025-06-12T06:54:48Z" + }, + { + "name": "bunkerity/bunkerweb", + "version": "v1.6.2", + "date": "2025-07-04T15:21:18Z" + }, + { + "name": "kimai/kimai", + "version": "2.37.0", + "date": "2025-07-04T14:49:43Z" + }, { "name": "Graylog2/graylog2-server", "version": "6.3.1", @@ -19,11 +59,6 @@ "version": "v25.2", "date": "2025-07-04T08:21:42Z" }, - { - "name": "bunkerity/bunkerweb", - "version": "v1.6.2", - "date": "2025-07-04T08:43:44Z" - }, { "name": "Checkmk/checkmk", "version": "v2.2.0p44", @@ -44,11 +79,6 @@ "version": "2.1.1", "date": "2025-06-14T17:45:06Z" }, - { - "name": "steveiliop56/tinyauth", - "version": "v3.4.1", - "date": "2025-06-11T07:53:44Z" - }, { "name": "outline/outline", "version": "v0.85.0", @@ -119,11 +149,6 @@ "version": "v1.12.2-rc.0", "date": "2025-07-03T00:31:22Z" }, - { - "name": "cross-seed/cross-seed", - "version": "v6.12.7", - "date": "2025-06-18T03:44:24Z" - }, { "name": "emqx/emqx", "version": "v5.8.7", @@ -149,11 +174,6 @@ "version": "v6.2.20", "date": "2025-07-02T04:03:37Z" }, - { - "name": "home-assistant/core", - "version": "2025.7.0", - "date": "2025-07-02T16:23:42Z" - }, { "name": "wazuh/wazuh", "version": "coverity-w27-4.13.0", @@ -299,11 +319,6 @@ "version": "v1.22.5", "date": "2025-06-28T16:06:19Z" }, - { - "name": "Luligu/matterbridge", - "version": "3.1.0", - "date": "2025-06-28T09:02:38Z" - }, { "name": "plexguide/Huntarr.io", "version": "8.1.11", @@ -319,11 +334,6 @@ "version": "v1.5.0", "date": "2025-06-27T22:04:32Z" }, - { - "name": "homarr-labs/homarr", - "version": "v1.26.0", - "date": "2025-06-27T19:15:24Z" - }, { "name": "goauthentik/authentik", "version": "version/2025.6.3", @@ -453,35 +463,5 @@ "name": "OliveTin/OliveTin", "version": "2025.6.22", "date": "2025-06-22T22:41:11Z" - }, - { - "name": "clusterzx/paperless-ai", - "version": "v3.0.7", - "date": "2025-06-22T17:49:29Z" - }, - { - "name": "TandoorRecipes/recipes", - "version": "1.5.35", - "date": "2025-06-22T08:30:10Z" - }, - { - "name": "inventree/InvenTree", - "version": "0.17.14", - "date": "2025-06-21T23:43:04Z" - }, - { - "name": "rogerfar/rdt-client", - "version": "v2.0.114", - "date": "2025-06-21T11:20:21Z" - }, - { - "name": "pocketbase/pocketbase", - "version": "v0.28.4", - "date": "2025-06-21T08:29:04Z" - }, - { - "name": "go-gitea/gitea", - "version": "v1.24.2", - "date": "2025-06-20T20:37:55Z" } ] From 3f4b39e8eb4326d8cce581b88a846d2b73d70fd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20B=C3=A9dard-Couture?= Date: Sat, 5 Jul 2025 07:57:40 -0400 Subject: [PATCH 197/463] Adds script to update LXC services from the host (#643) --- misc/build.func | 4 + tools/pve/update-apps.sh | 178 ++++++++++++++++++++++++++++++++------- 2 files changed, 153 insertions(+), 29 deletions(-) diff --git a/misc/build.func b/misc/build.func index 94fc86a2..4e596ae8 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1100,6 +1100,10 @@ start() { source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) if command -v pveversion >/dev/null 2>&1; then install_script + elif [ ! -z ${PHS_SILENT+x} ] && [[ "${PHS_SILENT}" == "1" ]]; then + VERBOSE="no" + set_std_mode + update_script else CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC Update/Setting" --menu \ "Support/Update functions for ${APP} LXC. Choose an option:" \ diff --git a/tools/pve/update-apps.sh b/tools/pve/update-apps.sh index e7712e4e..0c1a979f 100644 --- a/tools/pve/update-apps.sh +++ b/tools/pve/update-apps.sh @@ -1,9 +1,11 @@ #!/usr/bin/env bash # Copyright (c) 2021-2025 community-scripts ORG -# Author: BvdBerg01 +# Author: BvdBerg01 | Co-Author: remz1337 # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) + function header_info { clear cat <<"EOF" @@ -16,8 +18,6 @@ function header_info { EOF } -source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) - header_info echo "Loading..." whiptail --backtitle "Proxmox VE Helper Scripts" --title "LXC Container Update" --yesno "This will update LXC container. Proceed?" 10 58 || exit @@ -45,8 +45,8 @@ while read -r container; do done <<< "$containers" CHOICE=$(whiptail --title "LXC Container Update" \ - --radiolist "Select LXC container to update:" 25 60 13 \ - "${menu_items[@]}" 3>&2 2>&1 1>&3) + --checklist "Select LXC containers to update:" 25 60 13 \ + "${menu_items[@]}" 3>&2 2>&1 1>&3 | tr -d '"') if [ -z "$CHOICE" ]; then whiptail --title "LXC Container Update" \ @@ -55,12 +55,21 @@ if [ -z "$CHOICE" ]; then fi header_info -if(whiptail --backtitle "Proxmox VE Helper Scripts" --title "LXC Container Update" --yesno "Do you want to create a backup from your container?" 10 58); then +BACKUP_CHOICE="no" +if(whiptail --backtitle "Proxmox VE Helper Scripts" --title "LXC Container Update" --yesno "Do you want to backup your containers before update?" 10 58); then + BACKUP_CHOICE="yes" +fi +UNATTENDED_UPDATE="no" +if(whiptail --backtitle "Proxmox VE Helper Scripts" --title "LXC Container Update" --yesno "Run updates unattended?" 10 58); then + UNATTENDED_UPDATE="yes" +fi + +if [ "$BACKUP_CHOICE" == "yes" ]; then STORAGES=$(awk '/^(\S+):/ {storage=$2} /content.*backup/ {print storage}' /etc/pve/storage.cfg) if [ -z "$STORAGES" ]; then - whiptail --msgbox "Geen opslag met 'backup' gevonden!" 8 40 + whiptail --msgbox "No storage with 'backup' found!" 8 40 exit 1 fi @@ -75,37 +84,148 @@ if(whiptail --backtitle "Proxmox VE Helper Scripts" --title "LXC Container Updat msg_error "No storage selected!" exit 1 fi +fi - msg_info "Creating backup" - vzdump $CHOICE --compress zstd --storage $STORAGE_CHOICE -notes-template "community-scripts backup updater" > /dev/null 2>&1 +function backup_container(){ + msg_info "Creating backup for container $1" + vzdump $1 --compress zstd --storage $STORAGE_CHOICE -notes-template "community-scripts backup updater" > /dev/null 2>&1 status=$? if [ $status -eq 0 ]; then - msg_ok "Backup created" - pct exec $CHOICE -- update --from-pve - exit_code=$? + msg_ok "Backup created" else - msg_error "Backup failed" + msg_error "Backup failed for container $1" + exit 1 fi +} -else - pct exec $CHOICE -- update --from-pve - exit_code=$? +UPDATE_CMD="update;" +if [ "$UNATTENDED_UPDATE" == "yes" ];then + UPDATE_CMD="export PHS_SILENT=1;update;" fi -if [ $exit_code -eq 0 ]; then - msg_ok "Update completed" -else - msg_info "Restoring LXC from backup" - pct stop $CHOICE - LXC_STORAGE=$(pct config $CHOICE | awk -F '[:,]' '/rootfs/ {print $2}') - pct restore $CHOICE /var/lib/vz/dump/vzdump-lxc-$CHOICE-*.tar.zst --storage $LXC_STORAGE --force > /dev/null 2>&1 - pct start $CHOICE - restorestatus=$? - if [ $restorestatus -eq 0 ]; then - msg_ok "Restored LXC from backup" - else - msg_error "Restored LXC from backup failed" +containers_needing_reboot=() +for container in $CHOICE; do + msg_info "Updating container $container" + + if [ "BACKUP_CHOICE" == "yes" ];then + backup_container $container fi + #1) Detect service using the service name in the update command + pushd $(mktemp -d) >/dev/null + pct pull "$container" /usr/bin/update update 2>/dev/null + service=$(cat update | sed 's|.*/ct/||g' | sed 's|\.sh).*||g') + popd >/dev/null + + #1.1) If update script not detected, return + if [ -z "${service}" ]; then + echo -e "${YW}[WARN]${CL} Update script not found. Skipping to next container" + continue + else + echo -e "${BL}[INFO]${CL} Detected service: ${GN}${service}${CL}" + fi + + #2) Extract service build/update resource requirements from config/installation file + script=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${service}.sh) + config=$(pct config "$container") + build_cpu=$(echo "$script" | { grep -m 1 "var_cpu" || test $? = 1; } | sed 's|.*=||g' | sed 's|"||g' | sed 's|.*var_cpu:-||g' | sed 's|}||g') + build_ram=$(echo "$script" | { grep -m 1 "var_ram" || test $? = 1; } | sed 's|.*=||g' | sed 's|"||g' | sed 's|.*var_ram:-||g' | sed 's|}||g') + run_cpu=$(echo "$script" | { grep -m 1 "pct set \$CTID -cores" || test $? = 1; } | sed 's|.*cores ||g') + run_ram=$(echo "$script" | { grep -m 1 "pct set \$CTID -memory" || test $? = 1; } | sed 's|.*memory ||g') + current_cpu=$(echo "$config" | grep -m 1 "cores:" | sed 's|cores: ||g') + current_ram=$(echo "$config" | grep -m 1 "memory:" | sed 's|memory: ||g') + + #Test if all values are valid (>0) + if [ -z "${run_cpu}" ] || [ "$run_cpu" -le 0 ]; then + #echo "No valid value found for run_cpu. Assuming same as current configuration." + run_cpu=$current_cpu + fi + + if [ -z "${run_ram}" ] || [ "$run_ram" -le 0 ]; then + #echo "No valid value found for run_ram. Assuming same as current configuration." + run_ram=$current_ram + fi + + if [ -z "${build_cpu}" ] || [ "$build_cpu" -le 0 ]; then + #echo "No valid value found for build_cpu. Assuming same as current configuration." + build_cpu=$current_cpu + fi + + if [ -z "${build_ram}" ] || [ "$build_ram" -le 0 ]; then + #echo "No valid value found for build_ram. Assuming same as current configuration." + build_ram=$current_ram + fi + + UPDATE_BUILD_RESOURCES=0 + if [ "$build_cpu" -gt "$run_cpu" ] || [ "$build_ram" -gt "$run_ram" ]; then + UPDATE_BUILD_RESOURCES=1 + fi + + #3) if build resources are different than run resources, then: + if [ "$UPDATE_BUILD_RESOURCES" -eq "1" ]; then + pct set "$container" --cores "$build_cpu" --memory "$build_ram" + fi + + os=$(pct config "$container" | awk '/^ostype/ {print $2}') + + #4) Update service, using the update command + case "$os" in + alpine) pct exec "$container" -- ash -c "$UPDATE_CMD" ;; + archlinux) pct exec "$container" -- bash -c "$UPDATE_CMD" ;; + fedora | rocky | centos | alma) pct exec "$container" -- bash -c "$UPDATE_CMD" ;; + ubuntu | debian | devuan) pct exec "$container" -- bash -c "$UPDATE_CMD" ;; + opensuse) pct exec "$container" -- bash -c "$UPDATE_CMD" ;; + esac + exit_code=$? + + #5) if build resources are different than run resources, then: + if [ "$UPDATE_BUILD_RESOURCES" -eq "1" ]; then + pct set "$container" --cores "$run_cpu" --memory "$run_ram" + fi + + if pct exec "$container" -- [ -e "/var/run/reboot-required" ]; then + # Get the container's hostname and add it to the list + container_hostname=$(pct exec "$container" hostname) + containers_needing_reboot+=("$container ($container_hostname)") + fi + + if [ $exit_code -eq 0 ]; then + msg_ok "Updated container $container" + elif [ "BACKUP_CHOICE" == "yes" ];then + msg_info "Restoring LXC from backup" + pct stop $container + LXC_STORAGE=$(pct config $container | awk -F '[:,]' '/rootfs/ {print $2}') + pct restore $container /var/lib/vz/dump/vzdump-lxc-${container}-*.tar.zst --storage $LXC_STORAGE --force > /dev/null 2>&1 + pct start $container + restorestatus=$? + if [ $restorestatus -eq 0 ]; then + msg_ok "Restored LXC from backup" + else + msg_error "Restored LXC from backup failed" + exit 1 + fi + else + msg_error "Update failed for container $container. Exiting" + exit 1 + fi +done + +wait +header_info +echo -e "${GN}The process is complete, and the containers have been successfully updated.${CL}\n" +if [ "${#containers_needing_reboot[@]}" -gt 0 ]; then + echo -e "${RD}The following containers require a reboot:${CL}" + for container_name in "${containers_needing_reboot[@]}"; do + echo "$container_name" + done + echo -ne "${INFO} Do you wish to reboot these containers? " + read -r prompt + if [[ ${prompt,,} =~ ^(yes)$ ]]; then + echo -e "${CROSS}${HOLD} ${YWB}Rebooting containers.${CL}" + for container_name in "${containers_needing_reboot[@]}"; do + container=$(echo $container_name | cut -d " " -f 1) + pct reboot ${container} + done + fi fi From a3e429fd8e06abb4accf5465adc7ac1e265de65c Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Sat, 5 Jul 2025 12:35:57 +0000 Subject: [PATCH 198/463] Update versions.json (#683) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 65 ++++++++++++++++-------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 7bf1e201..e0f8b04e 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,34 @@ [ + { + "name": "runtipi/runtipi", + "version": "nightly", + "date": "2025-06-23T19:10:33Z" + }, + { + "name": "fuma-nama/fumadocs", + "version": "fumadocs-openapi@9.0.18", + "date": "2025-07-05T09:36:45Z" + }, + { + "name": "theonedev/onedev", + "version": "v11.11.4", + "date": "2025-07-05T09:23:25Z" + }, + { + "name": "Paymenter/Paymenter", + "version": "v1.2.0", + "date": "2025-07-05T08:58:05Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2120", + "date": "2025-07-05T05:58:02Z" + }, + { + "name": "linkwarden/linkwarden", + "version": "v2.11.3", + "date": "2025-07-05T04:34:46Z" + }, { "name": "steveiliop56/tinyauth", "version": "v3.4.1", @@ -39,6 +69,11 @@ "version": "2.37.0", "date": "2025-07-04T14:49:43Z" }, + { + "name": "keycloak/keycloak", + "version": "26.3.0", + "date": "2025-07-02T12:26:44Z" + }, { "name": "Graylog2/graylog2-server", "version": "6.3.1", @@ -49,11 +84,6 @@ "version": "preview-v0.1", "date": "2025-06-27T14:35:47Z" }, - { - "name": "theonedev/onedev", - "version": "v11.11.3", - "date": "2025-07-04T09:04:46Z" - }, { "name": "nzbgetcom/nzbget", "version": "v25.2", @@ -69,11 +99,6 @@ "version": "8.2-rc1-int", "date": "2025-07-02T19:27:08Z" }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2117", - "date": "2025-07-04T05:56:05Z" - }, { "name": "hyperion-project/hyperion.ng", "version": "2.1.1", @@ -89,11 +114,6 @@ "version": "15.2", "date": "2025-04-14T15:37:12Z" }, - { - "name": "keycloak/keycloak", - "version": "26.3.0", - "date": "2025-07-02T12:26:44Z" - }, { "name": "cloudflare/cloudflared", "version": "2025.7.0", @@ -124,11 +144,6 @@ "version": "18.0.7", "date": "2025-07-03T08:57:21Z" }, - { - "name": "fuma-nama/fumadocs", - "version": "fumadocs-openapi@9.0.17", - "date": "2025-07-03T06:57:48Z" - }, { "name": "esphome/esphome", "version": "2025.6.3", @@ -309,11 +324,6 @@ "version": "0.50.5", "date": "2025-06-29T08:54:47Z" }, - { - "name": "linkwarden/linkwarden", - "version": "v2.11.2", - "date": "2025-06-28T17:33:38Z" - }, { "name": "msgbyte/tianji", "version": "v1.22.5", @@ -444,11 +454,6 @@ "version": "RELEASE.2025-06-13T11-33-47Z", "date": "2025-06-23T20:58:42Z" }, - { - "name": "runtipi/runtipi", - "version": "nightly", - "date": "2025-06-23T19:10:33Z" - }, { "name": "VictoriaMetrics/VictoriaMetrics", "version": "pmm-6401-v1.120.0", From d44f49811f4289508879612e4d1454ed77829f5d Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Sun, 6 Jul 2025 01:47:04 +0000 Subject: [PATCH 199/463] Update versions.json (#684) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 84 +++++++++++++++--------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index e0f8b04e..6c4aa3ab 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,8 +1,48 @@ [ + { + "name": "hyperion-project/hyperion.ng", + "version": "2.1.1", + "date": "2025-06-14T17:45:06Z" + }, + { + "name": "steveiliop56/tinyauth", + "version": "v3.4.1", + "date": "2025-06-11T07:53:44Z" + }, + { + "name": "slskd/slskd", + "version": "0.23.0", + "date": "2025-07-06T00:02:35Z" + }, + { + "name": "Kareadita/Kavita", + "version": "v0.8.7", + "date": "2025-07-05T20:08:58Z" + }, + { + "name": "msgbyte/tianji", + "version": "v1.22.6", + "date": "2025-07-05T18:38:31Z" + }, + { + "name": "cross-seed/cross-seed", + "version": "v6.12.7", + "date": "2025-06-18T03:44:24Z" + }, + { + "name": "fallenbagel/jellyseerr", + "version": "preview-seerr", + "date": "2025-07-05T16:51:13Z" + }, + { + "name": "nicolargo/glances", + "version": "v4.3.2", + "date": "2025-07-05T16:00:15Z" + }, { "name": "runtipi/runtipi", - "version": "nightly", - "date": "2025-06-23T19:10:33Z" + "version": "v4.3.0", + "date": "2025-07-05T12:14:52Z" }, { "name": "fuma-nama/fumadocs", @@ -29,16 +69,6 @@ "version": "v2.11.3", "date": "2025-07-05T04:34:46Z" }, - { - "name": "steveiliop56/tinyauth", - "version": "v3.4.1", - "date": "2025-06-11T07:53:44Z" - }, - { - "name": "cross-seed/cross-seed", - "version": "v6.12.7", - "date": "2025-06-18T03:44:24Z" - }, { "name": "home-assistant/core", "version": "2025.7.1", @@ -99,11 +129,6 @@ "version": "8.2-rc1-int", "date": "2025-07-02T19:27:08Z" }, - { - "name": "hyperion-project/hyperion.ng", - "version": "2.1.1", - "date": "2025-06-14T17:45:06Z" - }, { "name": "outline/outline", "version": "v0.85.0", @@ -324,11 +349,6 @@ "version": "0.50.5", "date": "2025-06-29T08:54:47Z" }, - { - "name": "msgbyte/tianji", - "version": "v1.22.5", - "date": "2025-06-28T16:06:19Z" - }, { "name": "plexguide/Huntarr.io", "version": "8.1.11", @@ -364,11 +384,6 @@ "version": "flowise@3.0.3", "date": "2025-06-27T09:53:57Z" }, - { - "name": "fallenbagel/jellyseerr", - "version": "preview-seerr", - "date": "2025-06-27T06:10:03Z" - }, { "name": "MediaBrowser/Emby.Releases", "version": "4.9.1.2", @@ -453,20 +468,5 @@ "name": "minio/minio", "version": "RELEASE.2025-06-13T11-33-47Z", "date": "2025-06-23T20:58:42Z" - }, - { - "name": "VictoriaMetrics/VictoriaMetrics", - "version": "pmm-6401-v1.120.0", - "date": "2025-06-23T15:12:12Z" - }, - { - "name": "gotson/komga", - "version": "1.22.0", - "date": "2025-06-23T03:11:37Z" - }, - { - "name": "OliveTin/OliveTin", - "version": "2025.6.22", - "date": "2025-06-22T22:41:11Z" } ] From 1ba0e7f460b4122fbd33f1082a627a7dd96a99b3 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Sun, 6 Jul 2025 12:36:45 +0000 Subject: [PATCH 200/463] Update versions.json (#685) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 6c4aa3ab..605b7fb5 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,9 @@ [ + { + "name": "Jackett/Jackett", + "version": "v0.22.2123", + "date": "2025-07-06T06:01:32Z" + }, { "name": "hyperion-project/hyperion.ng", "version": "2.1.1", @@ -59,11 +64,6 @@ "version": "v1.2.0", "date": "2025-07-05T08:58:05Z" }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2120", - "date": "2025-07-05T05:58:02Z" - }, { "name": "linkwarden/linkwarden", "version": "v2.11.3", @@ -468,5 +468,20 @@ "name": "minio/minio", "version": "RELEASE.2025-06-13T11-33-47Z", "date": "2025-06-23T20:58:42Z" + }, + { + "name": "VictoriaMetrics/VictoriaMetrics", + "version": "pmm-6401-v1.120.0", + "date": "2025-06-23T15:12:12Z" + }, + { + "name": "gotson/komga", + "version": "1.22.0", + "date": "2025-06-23T03:11:37Z" + }, + { + "name": "OliveTin/OliveTin", + "version": "2025.6.22", + "date": "2025-06-22T22:41:11Z" } ] From 5ddc43b30e086a3cb629c3ece28ec00449ebbdec Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 01:45:50 +0000 Subject: [PATCH 201/463] Update versions.json (#686) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 144 +++++++++++++++-------------- 1 file changed, 77 insertions(+), 67 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 605b7fb5..16fe7d4b 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,14 +1,4 @@ [ - { - "name": "Jackett/Jackett", - "version": "v0.22.2123", - "date": "2025-07-06T06:01:32Z" - }, - { - "name": "hyperion-project/hyperion.ng", - "version": "2.1.1", - "date": "2025-06-14T17:45:06Z" - }, { "name": "steveiliop56/tinyauth", "version": "v3.4.1", @@ -16,29 +6,94 @@ }, { "name": "slskd/slskd", - "version": "0.23.0", - "date": "2025-07-06T00:02:35Z" + "version": "0.23.1", + "date": "2025-07-06T23:57:52Z" + }, + { + "name": "pelican-dev/panel", + "version": "v1.0.0-beta22", + "date": "2025-07-06T21:16:00Z" + }, + { + "name": "pelican-dev/wings", + "version": "v1.0.0-beta14", + "date": "2025-07-06T21:07:07Z" + }, + { + "name": "pocket-id/pocket-id", + "version": "v1.6.1", + "date": "2025-07-06T20:59:34Z" + }, + { + "name": "Luligu/matterbridge", + "version": "3.1.2", + "date": "2025-07-06T20:55:23Z" + }, + { + "name": "bluenviron/mediamtx", + "version": "v1.13.0", + "date": "2025-07-06T19:23:55Z" + }, + { + "name": "syncthing/syncthing", + "version": "v1.30.0", + "date": "2025-07-01T11:29:11Z" + }, + { + "name": "traccar/traccar", + "version": "v6.8.0", + "date": "2025-07-06T18:19:05Z" + }, + { + "name": "firefly-iii/firefly-iii", + "version": "v6.2.20", + "date": "2025-07-02T04:03:37Z" + }, + { + "name": "msgbyte/tianji", + "version": "v1.23.0", + "date": "2025-07-06T16:01:58Z" + }, + { + "name": "TandoorRecipes/recipes", + "version": "1.5.35", + "date": "2025-06-22T08:30:10Z" + }, + { + "name": "Part-DB/Part-DB-server", + "version": "v1.17.2", + "date": "2025-07-06T12:21:52Z" + }, + { + "name": "redis/redis", + "version": "8.0.3", + "date": "2025-07-06T12:19:24Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2123", + "date": "2025-07-06T06:01:32Z" + }, + { + "name": "fallenbagel/jellyseerr", + "version": "preview-OIDC", + "date": "2025-07-06T00:51:06Z" + }, + { + "name": "hyperion-project/hyperion.ng", + "version": "2.1.1", + "date": "2025-06-14T17:45:06Z" }, { "name": "Kareadita/Kavita", "version": "v0.8.7", "date": "2025-07-05T20:08:58Z" }, - { - "name": "msgbyte/tianji", - "version": "v1.22.6", - "date": "2025-07-05T18:38:31Z" - }, { "name": "cross-seed/cross-seed", "version": "v6.12.7", "date": "2025-06-18T03:44:24Z" }, - { - "name": "fallenbagel/jellyseerr", - "version": "preview-seerr", - "date": "2025-07-05T16:51:13Z" - }, { "name": "nicolargo/glances", "version": "v4.3.2", @@ -74,11 +129,6 @@ "version": "2025.7.1", "date": "2025-07-04T20:02:52Z" }, - { - "name": "Luligu/matterbridge", - "version": "3.1.1", - "date": "2025-07-04T19:50:37Z" - }, { "name": "homarr-labs/homarr", "version": "v1.27.0", @@ -124,11 +174,6 @@ "version": "v2.2.0p44", "date": "2025-07-04T06:44:06Z" }, - { - "name": "redis/redis", - "version": "8.2-rc1-int", - "date": "2025-07-02T19:27:08Z" - }, { "name": "outline/outline", "version": "v0.85.0", @@ -209,11 +254,6 @@ "version": "v0.9.5", "date": "2025-07-02T18:39:28Z" }, - { - "name": "firefly-iii/firefly-iii", - "version": "v6.2.20", - "date": "2025-07-02T04:03:37Z" - }, { "name": "wazuh/wazuh", "version": "coverity-w27-4.13.0", @@ -279,11 +319,6 @@ "version": "v1.133.0", "date": "2025-07-01T15:13:42Z" }, - { - "name": "syncthing/syncthing", - "version": "v1.30.0", - "date": "2025-07-01T11:29:11Z" - }, { "name": "rcourtman/Pulse", "version": "v99.99.99", @@ -359,11 +394,6 @@ "version": "v3.2.4", "date": "2025-06-28T02:47:31Z" }, - { - "name": "pocket-id/pocket-id", - "version": "v1.5.0", - "date": "2025-06-27T22:04:32Z" - }, { "name": "goauthentik/authentik", "version": "version/2025.6.3", @@ -459,29 +489,9 @@ "version": "v25.2.0", "date": "2025-06-24T17:06:31Z" }, - { - "name": "arunavo4/gitea-mirror", - "version": "v2.18.0", - "date": "2025-06-24T08:29:55Z" - }, { "name": "minio/minio", "version": "RELEASE.2025-06-13T11-33-47Z", "date": "2025-06-23T20:58:42Z" - }, - { - "name": "VictoriaMetrics/VictoriaMetrics", - "version": "pmm-6401-v1.120.0", - "date": "2025-06-23T15:12:12Z" - }, - { - "name": "gotson/komga", - "version": "1.22.0", - "date": "2025-06-23T03:11:37Z" - }, - { - "name": "OliveTin/OliveTin", - "version": "2025.6.22", - "date": "2025-06-22T22:41:11Z" } ] From 5c3f50289bffc57bd724557917fe3f9deab83b2e Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 7 Jul 2025 08:36:05 +0200 Subject: [PATCH 202/463] Update install.func --- misc/install.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/install.func b/misc/install.func index ddb78bc9..e3751c29 100644 --- a/misc/install.func +++ b/misc/install.func @@ -134,7 +134,7 @@ update_os() { msg_info "Updating Container OS" if [[ "$CACHER" == "yes" ]]; then echo "Acquire::http::Proxy-Auto-Detect \"/usr/local/bin/apt-proxy-detect.sh\";" >/etc/apt/apt.conf.d/00aptproxy - cat </usr/local/bin/apt-proxy-detect.sh + cat <<'EOF' >/usr/local/bin/apt-proxy-detect.sh #!/bin/bash if nc -w1 -z "${CACHER_IP}" 3142; then echo -n "http://${CACHER_IP}:3142" From 9407b4d768ad1205988e305658fccef018b11b75 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 7 Jul 2025 08:37:13 +0200 Subject: [PATCH 203/463] Update tools.func --- misc/tools.func | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 0ed2eca2..99db6d99 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -749,11 +749,12 @@ function fetch_and_deploy_gh_release() { local mode="${3:-tarball}" # tarball | binary | prebuild | singlefile local version="${4:-latest}" local target="${5:-/opt/$app}" + local asset_pattern="${6:-}" local app_lc=$(echo "${app,,}" | tr -d ' ') local version_file="$HOME/.${app_lc}" - local api_timeout="--connect-timeout 5 --max-time 10" + local api_timeout="--connect-timeout 10 --max-time 60" local download_timeout="--connect-timeout 15 --max-time 900" local current_version="" @@ -768,6 +769,14 @@ function fetch_and_deploy_gh_release() { local header=() [[ -n "${GITHUB_TOKEN:-}" ]] && header=(-H "Authorization: token $GITHUB_TOKEN") + # dns pre check + local gh_host + gh_host=$(awk -F/ '{print $3}' <<<"$api_url") + if ! getent hosts "$gh_host" &>/dev/null; then + msg_error "DNS resolution failed for $gh_host – check /etc/resolv.conf or networking" + return 1 + fi + local max_retries=3 retry_delay=2 attempt=1 success=false resp http_code while ((attempt <= max_retries)); do @@ -777,7 +786,7 @@ function fetch_and_deploy_gh_release() { done if ! $success; then - msg_error "Failed to fetch release metadata after $max_retries attempts" + msg_error "Failed to fetch release metadata from $api_url after $max_retries attempts" return 1 fi @@ -801,7 +810,7 @@ function fetch_and_deploy_gh_release() { tmpdir=$(mktemp -d) || return 1 local filename="" url="" - msg_info "Setup $app ($version)" + msg_info "Fetching GitHub release: $app ($version)" ### Tarball Mode ### if [[ "$mode" == "tarball" || "$mode" == "source" ]]; then @@ -835,9 +844,9 @@ function fetch_and_deploy_gh_release() { assets=$(echo "$json" | jq -r '.assets[].browser_download_url') # If explicit filename pattern is provided (param $6), match that first - if [[ -n "$6" ]]; then + if [[ -n "$asset_pattern" ]]; then for u in $assets; do - [[ "$u" =~ $6 || "$u" == *"$6" ]] && url_match="$u" && break + [[ "$u" =~ $asset_pattern || "$u" == *"$asset_pattern" ]] && url_match="$u" && break done fi @@ -973,7 +982,7 @@ function fetch_and_deploy_gh_release() { fi echo "$version" >"$version_file" - msg_ok "Setup $app ($version)" + msg_ok "Deployed: $app ($version)" rm -rf "$tmpdir" } From 5a7ed724df5678b4768da5349a1f395896d817f4 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 7 Jul 2025 09:37:47 +0200 Subject: [PATCH 204/463] Update filebrowser.sh --- tools/addon/filebrowser.sh | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/tools/addon/filebrowser.sh b/tools/addon/filebrowser.sh index 29015d31..b648c155 100644 --- a/tools/addon/filebrowser.sh +++ b/tools/addon/filebrowser.sh @@ -88,7 +88,7 @@ if [ -f "$INSTALL_PATH" ]; then read -r -p "Would you like to update ${APP}? (y/N): " update_prompt if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Updating ${APP}" - curl -fsSL https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/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 "Updated ${APP}" exit 0 @@ -106,7 +106,7 @@ 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}" $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 + 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}" @@ -119,22 +119,17 @@ if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then chmod 644 "$DB_PATH" msg_ok "Directory created successfully" + cd /usr/local/community-scripts + filebrowser config init &>/dev/null + filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null + filebrowser users add admin helper-scripts.com --perm.admin --database "$DB_PATH" &>/dev/null + read -r -p "Would you like to use No Authentication? (y/N): " auth_prompt if [[ "${auth_prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Configuring No Authentication" - cd /usr/local/community-scripts - 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 init --auth.method=noauth &>/dev/null filebrowser config set --auth.method=noauth &>/dev/null - filebrowser users add ID 1 --perm.admin &>/dev/null msg_ok "No Authentication configured" else - msg_info "Setting up default authentication" - cd /usr/local/community-scripts - 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 helper-scripts.com --perm.admin --database "$DB_PATH" &>/dev/null msg_ok "Default authentication configured (admin:helper-scripts.com)" fi @@ -149,8 +144,8 @@ After=network-online.target User=root WorkingDirectory=/usr/local/community-scripts ExecStartPre=/bin/touch /usr/local/community-scripts/filebrowser.db -ExecStartPre=/usr/local/bin/filebrowser config set -a "0.0.0.0" -p 9000 -d /usr/local/community-scripts/filebrowser.db -ExecStart=/usr/local/bin/filebrowser -r / -d /usr/local/community-scripts/filebrowser.db -p 9000 +ExecStartPre=/usr/local/bin/filebrowser config set -a "0.0.0.0" -p ${PORT} -d /usr/local/community-scripts/filebrowser.db +ExecStart=/usr/local/bin/filebrowser -r / -d /usr/local/community-scripts/filebrowser.db -p ${PORT} Restart=always [Install] From 79d3bdbcefd95ce57822220140cdf698e2bda045 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 7 Jul 2025 10:00:33 +0200 Subject: [PATCH 205/463] Update tools.func --- misc/tools.func | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/misc/tools.func b/misc/tools.func index 99db6d99..a69c95b1 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -931,7 +931,11 @@ function fetch_and_deploy_gh_release() { fi $STD unzip "$tmpdir/$filename" -d "$target" elif [[ "$filename" == *.tar.* ]]; then - tar --strip-components=1 -xf "$tmpdir/$filename" -C "$target" + if tar -tf "$tmpdir/$filename" | grep -qE '^([^/]+/){2}'; then + tar --strip-components=1 -xf "$tmpdir/$filename" -C "$target" + else + tar -xf "$tmpdir/$filename" -C "$target" + fi else msg_error "Unsupported archive format: $filename" rm -rf "$tmpdir" From 6618422ec1ac4846bab3ff23f08784ab25799814 Mon Sep 17 00:00:00 2001 From: Tobias <96661824+CrazyWolf13@users.noreply.github.com> Date: Mon, 7 Jul 2025 10:53:27 +0200 Subject: [PATCH 206/463] Update gitea-mirror.sh --- ct/gitea-mirror.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/gitea-mirror.sh b/ct/gitea-mirror.sh index 16a497c2..dafdfb78 100644 --- a/ct/gitea-mirror.sh +++ b/ct/gitea-mirror.sh @@ -49,7 +49,7 @@ function update_script() { rm -rf /opt/gitea-mirror fi - RELEASE=$(curl -fsSL https://api.github.com/repos/arunavo4/gitea-mirror/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') + RELEASE=$(curl -fsSL https://api.github.com/repos/RayLabsHQ/gitea-mirror/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') if [[ "${RELEASE}" != "$(cat ~/.${APP} 2>/dev/null || cat /opt/${APP}_version.txt 2>/dev/null)" ]]; then msg_info "Stopping Services" @@ -71,7 +71,7 @@ function update_script() { msg_ok "Installed Bun" rm -rf /opt/gitea-mirror - fetch_and_deploy_gh_release "gitea-mirror" "arunavo4/gitea-mirror" "tarball" "v3.0.2" + fetch_and_deploy_gh_release "gitea-mirror" "RayLabsHQ/gitea-mirror" "tarball" "v3.0.2" msg_info "Updating and rebuilding ${APP} to v${RELEASE}" cd /opt/gitea-mirror From 47ab92fa9a49a0183f7dcb3f60cf445f245e06bf Mon Sep 17 00:00:00 2001 From: Tobias <96661824+CrazyWolf13@users.noreply.github.com> Date: Mon, 7 Jul 2025 10:54:01 +0200 Subject: [PATCH 207/463] Update gitea-mirror-install.sh --- install/gitea-mirror-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/gitea-mirror-install.sh b/install/gitea-mirror-install.sh index e8a00cac..a1c68c17 100644 --- a/install/gitea-mirror-install.sh +++ b/install/gitea-mirror-install.sh @@ -3,7 +3,7 @@ # Copyright (c) 2021-2025 community-scripts ORG # Author: CrazyWolf13 # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/arunavo4/gitea-mirror +# Source: https://github.com/RayLabsHQ/gitea-mirror source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color @@ -28,7 +28,7 @@ ln -sf /opt/bun/bin/bun /usr/local/bin/bun ln -sf /opt/bun/bin/bun /usr/local/bin/bunx msg_ok "Installed Bun" -fetch_and_deploy_gh_release "gitea-mirror" "arunavo4/gitea-mirror" "tarball" "v3.0.2" +fetch_and_deploy_gh_release "gitea-mirror" "RayLabsHQ/gitea-mirror" "tarball" "v3.0.2" msg_info "Installing gitea-mirror" cd /opt/gitea-mirror From 8e2be149ea8e9d8122bc02677e9ce1e9789ca015 Mon Sep 17 00:00:00 2001 From: Tobias <96661824+CrazyWolf13@users.noreply.github.com> Date: Mon, 7 Jul 2025 10:54:18 +0200 Subject: [PATCH 208/463] Update gitea-mirror.sh --- ct/gitea-mirror.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/gitea-mirror.sh b/ct/gitea-mirror.sh index dafdfb78..ce0e21ee 100644 --- a/ct/gitea-mirror.sh +++ b/ct/gitea-mirror.sh @@ -3,7 +3,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV # Copyright (c) 2021-2025 community-scripts ORG # Author: CrazyWolf13 # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/arunavo4/gitea-mirror +# Source: https://github.com/RayLabsHQ/gitea-mirror APP="gitea-mirror" var_tags="${var_tags:-mirror;gitea}" From 97e15357d934601e00bf5a46396c8892d375bf04 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 12:40:15 +0000 Subject: [PATCH 209/463] Update versions.json (#687) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 145 ++++++++++++----------------- 1 file changed, 60 insertions(+), 85 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 16fe7d4b..2ac285a1 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,59 @@ [ + { + "name": "VictoriaMetrics/VictoriaMetrics", + "version": "v1.121.0", + "date": "2025-07-07T11:32:39Z" + }, + { + "name": "meilisearch/meilisearch", + "version": "prototype-incremental-vector-store-3", + "date": "2025-07-07T10:27:19Z" + }, + { + "name": "Paymenter/Paymenter", + "version": "v1.2.1", + "date": "2025-07-07T10:11:26Z" + }, + { + "name": "Checkmk/checkmk", + "version": "v2.4.0p7-rc1", + "date": "2025-07-07T09:25:01Z" + }, + { + "name": "nzbgetcom/nzbget", + "version": "v25.2", + "date": "2025-07-04T08:21:42Z" + }, + { + "name": "zwave-js/zwave-js-ui", + "version": "v10.8.0", + "date": "2025-07-07T08:37:45Z" + }, + { + "name": "morpheus65535/bazarr", + "version": "v1.5.2", + "date": "2025-05-11T16:40:55Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2125", + "date": "2025-07-07T05:56:33Z" + }, + { + "name": "mattermost/mattermost", + "version": "preview-v0.1", + "date": "2025-06-27T14:35:47Z" + }, + { + "name": "MediaBrowser/Emby.Releases", + "version": "4.9.1.2", + "date": "2025-06-26T22:08:00Z" + }, + { + "name": "firefly-iii/firefly-iii", + "version": "v6.2.20", + "date": "2025-07-02T04:03:37Z" + }, { "name": "steveiliop56/tinyauth", "version": "v3.4.1", @@ -44,11 +99,6 @@ "version": "v6.8.0", "date": "2025-07-06T18:19:05Z" }, - { - "name": "firefly-iii/firefly-iii", - "version": "v6.2.20", - "date": "2025-07-02T04:03:37Z" - }, { "name": "msgbyte/tianji", "version": "v1.23.0", @@ -69,11 +119,6 @@ "version": "8.0.3", "date": "2025-07-06T12:19:24Z" }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2123", - "date": "2025-07-06T06:01:32Z" - }, { "name": "fallenbagel/jellyseerr", "version": "preview-OIDC", @@ -114,11 +159,6 @@ "version": "v11.11.4", "date": "2025-07-05T09:23:25Z" }, - { - "name": "Paymenter/Paymenter", - "version": "v1.2.0", - "date": "2025-07-05T08:58:05Z" - }, { "name": "linkwarden/linkwarden", "version": "v2.11.3", @@ -144,6 +184,11 @@ "version": "v1.6.2", "date": "2025-07-04T15:21:18Z" }, + { + "name": "emqx/emqx", + "version": "e6.0.0-M1.202507-alpha.1", + "date": "2025-07-04T14:58:23Z" + }, { "name": "kimai/kimai", "version": "2.37.0", @@ -159,21 +204,6 @@ "version": "6.3.1", "date": "2025-07-04T11:20:48Z" }, - { - "name": "mattermost/mattermost", - "version": "preview-v0.1", - "date": "2025-06-27T14:35:47Z" - }, - { - "name": "nzbgetcom/nzbget", - "version": "v25.2", - "date": "2025-07-04T08:21:42Z" - }, - { - "name": "Checkmk/checkmk", - "version": "v2.2.0p44", - "date": "2025-07-04T06:44:06Z" - }, { "name": "outline/outline", "version": "v0.85.0", @@ -234,11 +264,6 @@ "version": "v1.12.2-rc.0", "date": "2025-07-03T00:31:22Z" }, - { - "name": "emqx/emqx", - "version": "v5.8.7", - "date": "2025-07-02T21:54:54Z" - }, { "name": "hargata/lubelog", "version": "v1.4.8", @@ -414,11 +439,6 @@ "version": "flowise@3.0.3", "date": "2025-06-27T09:53:57Z" }, - { - "name": "MediaBrowser/Emby.Releases", - "version": "4.9.1.2", - "date": "2025-06-26T22:08:00Z" - }, { "name": "netbox-community/netbox", "version": "v4.3.3", @@ -439,11 +459,6 @@ "version": "v3.5.0-rc1", "date": "2025-06-26T15:08:43Z" }, - { - "name": "meilisearch/meilisearch", - "version": "prototype-no-simd-x86-arroy-0", - "date": "2025-06-26T14:54:18Z" - }, { "name": "AdguardTeam/AdGuardHome", "version": "v0.107.63", @@ -453,45 +468,5 @@ "name": "node-red/node-red", "version": "4.1.0-beta.2", "date": "2025-06-26T14:23:26Z" - }, - { - "name": "gristlabs/grist-core", - "version": "v1.6.1", - "date": "2025-06-25T21:19:25Z" - }, - { - "name": "coder/code-server", - "version": "v4.101.2", - "date": "2025-06-25T21:18:52Z" - }, - { - "name": "wavelog/wavelog", - "version": "2.0.5", - "date": "2025-06-25T14:53:31Z" - }, - { - "name": "moghtech/komodo", - "version": "v1.18.4", - "date": "2025-06-25T00:06:56Z" - }, - { - "name": "duplicati/duplicati", - "version": "v2.1.0.120-2.1.0.120_canary_2025-06-24", - "date": "2025-06-24T22:39:50Z" - }, - { - "name": "evcc-io/evcc", - "version": "0.204.5", - "date": "2025-06-24T19:17:16Z" - }, - { - "name": "ErsatzTV/ErsatzTV", - "version": "v25.2.0", - "date": "2025-06-24T17:06:31Z" - }, - { - "name": "minio/minio", - "version": "RELEASE.2025-06-13T11-33-47Z", - "date": "2025-06-23T20:58:42Z" } ] From 385d0dd5967481b16affc6b5ece2bd4112f8c2d8 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 7 Jul 2025 15:30:22 +0200 Subject: [PATCH 210/463] Update tools.func --- misc/tools.func | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/misc/tools.func b/misc/tools.func index a69c95b1..29401951 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1782,6 +1782,13 @@ function setup_ffmpeg() { $STD make -j"$(nproc)" $STD make install + echo "/usr/local/lib" >/etc/ld.so.conf.d/ffmpeg.conf + ldconfig + + ldconfig -p | grep libavdevice >/dev/null || { + msg_error "libavdevice not registered with dynamic linker" + return 1 + } if ! command -v ffmpeg &>/dev/null; then msg_error "FFmpeg installation failed" From e4684e343c52887a5a30405e971f165f8aa807e1 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 7 Jul 2025 15:37:18 +0200 Subject: [PATCH 211/463] Update tools.func --- misc/tools.func | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 29401951..7b9b0490 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1679,7 +1679,7 @@ function setup_ffmpeg() { local TMP_DIR TMP_DIR=$(mktemp -d) local GITHUB_REPO="FFmpeg/FFmpeg" - local VERSION="${FFMPEG_VERSION:-}" + local VERSION="${FFMPEG_VERSION:-latest}" local TYPE="${FFMPEG_TYPE:-full}" local BIN_PATH="/usr/local/bin/ffmpeg" @@ -1698,12 +1698,17 @@ function setup_ffmpeg() { return fi + if ! command -v jq &>/dev/null; then + $STD apt-get update + $STD apt-get install -y jq + fi + # Auto-detect latest stable version if none specified - if [[ -z "$VERSION" ]]; then - msg_info "Fetching latest stable FFmpeg tag" + if [[ "$VERSION" == "latest" || -z "$VERSION" ]]; then + msg_info "Resolving latest FFmpeg tag" VERSION=$(curl -fsSL "https://api.github.com/repos/${GITHUB_REPO}/tags" | jq -r '.[].name' | - grep -E '^n[0-9]+\.[0-9]+\.[0-9]+$' | # stable only + grep -E '^n[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n1) fi From aecc0a2ecf09abd6b60da067df32148c5b07ebd7 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 7 Jul 2025 15:40:47 +0200 Subject: [PATCH 212/463] ersatztv dev --- ct/ersatztv.sh | 69 +++++++++++++++++++++++++++++++++++++ install/ersatztv-install.sh | 57 ++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 ct/ersatztv.sh create mode 100644 install/ersatztv-install.sh diff --git a/ct/ersatztv.sh b/ct/ersatztv.sh new file mode 100644 index 00000000..381e1e17 --- /dev/null +++ b/ct/ersatztv.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 tteck +# Author: MickLesk (Canbiz) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://ersatztv.org/ + +APP="ErsatzTV" +var_tags="${var_tags:-iptv}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-1024}" +var_disk="${var_disk:-5}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +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/ErsatzTV ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + RELEASE=$(curl -fsSL https://api.github.com/repos/ErsatzTV/ErsatzTV/releases | grep -oP '"tag_name": "\K[^"]+' | head -n 1) + if [[ ! -f /opt/${APP}_version.txt && $(echo "x.x.x" >/opt/${APP}_version.txt) || "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + msg_info "Stopping ErsatzTV" + systemctl stop ersatzTV + msg_ok "Stopped ErsatzTV" + + msg_info "Updating ErsatzTV" + cp -R /opt/ErsatzTV/ ErsatzTV-backup + rm ErsatzTV-backup/ErsatzTV + rm -rf /opt/ErsatzTV + temp_file=$(mktemp) + curl -fsSL "https://github.com/ErsatzTV/ErsatzTV/releases/download/${RELEASE}/ErsatzTV-${RELEASE}-linux-x64.tar.gz" -o "$temp_file" + tar -xzf "$temp_file" + mv ErsatzTV-${RELEASE}-linux-x64 /opt/ErsatzTV + cp -R ErsatzTV-backup/* /opt/ErsatzTV/ + rm -rf ErsatzTV-backup + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Updated ErsatzTV" + + msg_info "Starting ErsatzTV" + systemctl start ersatzTV + msg_ok "Started ErsatzTV" + + msg_info "Cleaning Up" + rm -f ${temp_file} + msg_ok "Cleaned" + msg_ok "Updated Successfully" + else + msg_ok "No update required. ${APP} is already at ${RELEASE}" + 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}http://${IP}:8409${CL}" diff --git a/install/ersatztv-install.sh b/install/ersatztv-install.sh new file mode 100644 index 00000000..5e5b6ab5 --- /dev/null +++ b/install/ersatztv-install.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 tteck +# Author: MickLesk (Canbiz) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://ersatztv.org/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +FFMPEG_VERSION="latest" FFMPEG_TYPE="full" setup_ffmpeg + +msg_info "Setting Up Hardware Acceleration" +$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} +if [[ "$CTTYPE" == "0" ]]; then + chgrp video /dev/dri + chmod 755 /dev/dri + chmod 660 /dev/dri/* + $STD adduser $(id -u -n) video + $STD adduser $(id -u -n) render +fi +msg_ok "Set Up Hardware Acceleration" + +fetch_and_deploy_gh_release "ersatztv" "ErsatzTV/ErsatzTV" "prebuild" "latest" "/opt/ErsatzTV" "ErsatzTV-.*linux-x64.tar.gz" + +msg_info "Creating Service" +cat </etc/systemd/system/ersatzTV.service +[Unit] +Description=ErsatzTV Service +After=multi-user.target + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/ErsatzTV +ExecStart=/opt/ErsatzTV/ErsatzTV +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now ersatzTV +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 2aa70c67e80a1518f191ef4754c2b600bae0d107 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 13:41:16 +0000 Subject: [PATCH 213/463] Update .app files (#688) Co-authored-by: GitHub Actions --- ct/headers/ersatztv | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ct/headers/ersatztv diff --git a/ct/headers/ersatztv b/ct/headers/ersatztv new file mode 100644 index 00000000..f47317c3 --- /dev/null +++ b/ct/headers/ersatztv @@ -0,0 +1,6 @@ + ______ __ _______ __ + / ____/_____________ _/ /_____/_ __/ | / / + / __/ / ___/ ___/ __ `/ __/_ / / / | | / / + / /___/ / (__ ) /_/ / /_ / /_/ / | |/ / +/_____/_/ /____/\__,_/\__/ /___/_/ |___/ + From eb2b679e5e683fb28530d84a23acbe4dd0603e02 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 7 Jul 2025 15:44:05 +0200 Subject: [PATCH 214/463] vaapi --- misc/build.func | 3 --- misc/core.func | 1 - 2 files changed, 4 deletions(-) diff --git a/misc/build.func b/misc/build.func index 4e596ae8..42d4260d 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1254,13 +1254,10 @@ EOF echo "" msg_custom "⚙️ " "\e[96m" "Configuring VAAPI passthrough for LXC container" - if [ "$CT_TYPE" != "0" ]; then msg_custom "⚠️ " "\e[33m" "Container is unprivileged – VAAPI passthrough may not work without additional host configuration (e.g., idmap)." fi - msg_custom "ℹ️ " "\e[96m" "VAAPI enables GPU hardware acceleration (e.g., for video transcoding in Jellyfin or Plex)." - echo "" read -rp "➤ Automatically mount all available VAAPI devices? [Y/n]: " VAAPI_ALL diff --git a/misc/core.func b/misc/core.func index e313ea18..a8774fc2 100644 --- a/misc/core.func +++ b/misc/core.func @@ -413,7 +413,6 @@ msg_custom() { [[ -z "$msg" ]] && return stop_spinner echo -e "${BFR:-} ${symbol} ${color}${msg}${CL:-\e[0m}" - printf "\r\033[K\e[?25h\n" } # msg_ok() { From 3480249c27713b6e5bc6763976cbd5812b86152f Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 7 Jul 2025 16:01:27 +0200 Subject: [PATCH 215/463] Update ersatztv-install.sh --- install/ersatztv-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/ersatztv-install.sh b/install/ersatztv-install.sh index 5e5b6ab5..728a0fdc 100644 --- a/install/ersatztv-install.sh +++ b/install/ersatztv-install.sh @@ -26,7 +26,7 @@ if [[ "$CTTYPE" == "0" ]]; then fi msg_ok "Set Up Hardware Acceleration" -fetch_and_deploy_gh_release "ersatztv" "ErsatzTV/ErsatzTV" "prebuild" "latest" "/opt/ErsatzTV" "ErsatzTV-.*linux-x64.tar.gz" +fetch_and_deploy_gh_release "ersatztv" "ErsatzTV/ErsatzTV" "prebuild" "latest" "/opt/ErsatzTV" "*linux-x64.tar.gz" msg_info "Creating Service" cat </etc/systemd/system/ersatzTV.service From 369f2ef850f30d2fd785cbdb08a5400c5c48d104 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 7 Jul 2025 16:01:38 +0200 Subject: [PATCH 216/463] Update ersatztv-install.sh --- install/ersatztv-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/ersatztv-install.sh b/install/ersatztv-install.sh index 728a0fdc..eb0cc2f6 100644 --- a/install/ersatztv-install.sh +++ b/install/ersatztv-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -FFMPEG_VERSION="latest" FFMPEG_TYPE="full" setup_ffmpeg +FFMPEG_VERSION="latest" FFMPEG_TYPE="medium" setup_ffmpeg msg_info "Setting Up Hardware Acceleration" $STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} From d361d23a2d2326968b50b9b311a8b5c74036fc46 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 7 Jul 2025 19:50:00 +0200 Subject: [PATCH 217/463] Update tools.func --- misc/tools.func | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 7b9b0490..0547d2f0 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -929,13 +929,27 @@ function fetch_and_deploy_gh_release() { if ! command -v unzip &>/dev/null; then $STD apt-get install -y unzip fi - $STD unzip "$tmpdir/$filename" -d "$target" + + local top_level_entries + top_level_entries=$(unzip -l "$tmpdir/$filename" | awk '{print $4}' | grep -v '^$' | cut -d/ -f1 | sort -u) + + if [[ $(wc -l <<<"$top_level_entries") -eq 1 ]]; then + unzip -q "$tmpdir/$filename" -d "$tmpdir/unzip" + shopt -s dotglob nullglob + cp -r "$tmpdir/unzip/"* "$target/" + shopt -u dotglob nullglob + else + unzip -q "$tmpdir/$filename" -d "$target" + fi + elif [[ "$filename" == *.tar.* ]]; then - if tar -tf "$tmpdir/$filename" | grep -qE '^([^/]+/){2}'; then + local top_level_entries + top_level_entries=$(tar -tf "$tmpdir/$filename" | cut -d/ -f1 | sort -u) + + if [[ $(wc -l <<<"$top_level_entries") -eq 1 ]]; then tar --strip-components=1 -xf "$tmpdir/$filename" -C "$target" else tar -xf "$tmpdir/$filename" -C "$target" - fi else msg_error "Unsupported archive format: $filename" rm -rf "$tmpdir" From ce33ab61b5a8a75533a4d3282d01a76a8915fd65 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 7 Jul 2025 19:52:25 +0200 Subject: [PATCH 218/463] Update tools.func --- misc/tools.func | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/tools.func b/misc/tools.func index 0547d2f0..c354cff7 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -925,7 +925,7 @@ function fetch_and_deploy_gh_release() { } mkdir -p "$target" - if [[ "$filename" == *.zip ]]; then + if [[ "$filename" == *.zip ]]; then if ! command -v unzip &>/dev/null; then $STD apt-get install -y unzip fi @@ -950,6 +950,7 @@ function fetch_and_deploy_gh_release() { tar --strip-components=1 -xf "$tmpdir/$filename" -C "$target" else tar -xf "$tmpdir/$filename" -C "$target" + fi else msg_error "Unsupported archive format: $filename" rm -rf "$tmpdir" From e104f11fb0a76149a3acd3fb5e73f57365c36248 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 01:41:17 +0000 Subject: [PATCH 219/463] Update versions.json (#689) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 109 ++++++++++++++++++----------- 1 file changed, 67 insertions(+), 42 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 2ac285a1..56687f7c 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,8 +1,68 @@ [ + { + "name": "ollama/ollama", + "version": "v0.9.5", + "date": "2025-07-02T18:39:28Z" + }, + { + "name": "steveiliop56/tinyauth", + "version": "v3.4.1", + "date": "2025-06-11T07:53:44Z" + }, + { + "name": "mongodb/mongo", + "version": "r8.0.12-rc0", + "date": "2025-07-07T23:35:35Z" + }, + { + "name": "Stirling-Tools/Stirling-PDF", + "version": "v1.0.1", + "date": "2025-07-07T23:01:28Z" + }, + { + "name": "duplicati/duplicati", + "version": "v2.1.0.122-2.1.0.122_canary_2025-07-07", + "date": "2025-07-07T17:54:52Z" + }, + { + "name": "msgbyte/tianji", + "version": "v1.23.2", + "date": "2025-07-07T16:51:43Z" + }, + { + "name": "TandoorRecipes/recipes", + "version": "1.5.35", + "date": "2025-06-22T08:30:10Z" + }, { "name": "VictoriaMetrics/VictoriaMetrics", - "version": "v1.121.0", - "date": "2025-07-07T11:32:39Z" + "version": "pmm-6401-v1.121.0", + "date": "2025-07-07T16:16:13Z" + }, + { + "name": "n8n-io/n8n", + "version": "n8n@1.100.0", + "date": "2025-06-23T12:48:35Z" + }, + { + "name": "photoprism/photoprism", + "version": "250707-d28b3101e", + "date": "2025-07-07T15:15:21Z" + }, + { + "name": "Checkmk/checkmk", + "version": "v2.4.0p7-rc2", + "date": "2025-07-07T15:07:57Z" + }, + { + "name": "traccar/traccar", + "version": "v6.8.1", + "date": "2025-07-07T14:40:11Z" + }, + { + "name": "BookStackApp/BookStack", + "version": "v25.05.2", + "date": "2025-07-07T14:08:25Z" }, { "name": "meilisearch/meilisearch", @@ -14,11 +74,6 @@ "version": "v1.2.1", "date": "2025-07-07T10:11:26Z" }, - { - "name": "Checkmk/checkmk", - "version": "v2.4.0p7-rc1", - "date": "2025-07-07T09:25:01Z" - }, { "name": "nzbgetcom/nzbget", "version": "v25.2", @@ -54,11 +109,6 @@ "version": "v6.2.20", "date": "2025-07-02T04:03:37Z" }, - { - "name": "steveiliop56/tinyauth", - "version": "v3.4.1", - "date": "2025-06-11T07:53:44Z" - }, { "name": "slskd/slskd", "version": "0.23.1", @@ -94,21 +144,6 @@ "version": "v1.30.0", "date": "2025-07-01T11:29:11Z" }, - { - "name": "traccar/traccar", - "version": "v6.8.0", - "date": "2025-07-06T18:19:05Z" - }, - { - "name": "msgbyte/tianji", - "version": "v1.23.0", - "date": "2025-07-06T16:01:58Z" - }, - { - "name": "TandoorRecipes/recipes", - "version": "1.5.35", - "date": "2025-06-22T08:30:10Z" - }, { "name": "Part-DB/Part-DB-server", "version": "v1.17.2", @@ -234,11 +269,6 @@ "version": "310.5", "date": "2025-07-03T14:05:25Z" }, - { - "name": "n8n-io/n8n", - "version": "n8n@1.100.0", - "date": "2025-06-23T12:48:35Z" - }, { "name": "Dolibarr/dolibarr", "version": "18.0.7", @@ -254,11 +284,6 @@ "version": "v25.7.1", "date": "2025-07-03T01:03:18Z" }, - { - "name": "mongodb/mongo", - "version": "r6.0.25-rc0", - "date": "2025-07-03T00:44:52Z" - }, { "name": "documenso/documenso", "version": "v1.12.2-rc.0", @@ -274,11 +299,6 @@ "version": "2.5.1", "date": "2025-07-02T19:38:06Z" }, - { - "name": "ollama/ollama", - "version": "v0.9.5", - "date": "2025-07-02T18:39:28Z" - }, { "name": "wazuh/wazuh", "version": "coverity-w27-4.13.0", @@ -468,5 +488,10 @@ "name": "node-red/node-red", "version": "4.1.0-beta.2", "date": "2025-06-26T14:23:26Z" + }, + { + "name": "gristlabs/grist-core", + "version": "v1.6.1", + "date": "2025-06-25T21:19:25Z" } ] From edebef124379b2d5bb7478759b787abba3584c24 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 07:59:03 +0200 Subject: [PATCH 220/463] cleanup --- ct/alpine-komodo.sh | 58 ----------- ct/alpine-tinyauth.sh | 58 ----------- ct/stirling-pdf.sh | 62 ++++++++++++ install/alpine-komodo-install.sh | 79 --------------- install/alpine-tinyauth-install.sh | 90 ----------------- install/npmplus-install.sh | 114 --------------------- install/stirling-pdf-install.sh | 154 +++++++++++++++++++++++++++++ 7 files changed, 216 insertions(+), 399 deletions(-) delete mode 100644 ct/alpine-komodo.sh delete mode 100644 ct/alpine-tinyauth.sh create mode 100644 ct/stirling-pdf.sh delete mode 100644 install/alpine-komodo-install.sh delete mode 100644 install/alpine-tinyauth-install.sh delete mode 100644 install/npmplus-install.sh create mode 100644 install/stirling-pdf-install.sh diff --git a/ct/alpine-komodo.sh b/ct/alpine-komodo.sh deleted file mode 100644 index f7ef40a4..00000000 --- a/ct/alpine-komodo.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2025 community-scripts ORG -# Author: MickLesk (CanbiZ) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://komo.do - -APP="Alpine-Komodo" -var_tags="${var_tags:-docker,alpine}" -var_cpu="${var_cpu:-1}" -var_ram="${var_ram:-1024}" -var_disk="${var_disk:-10}" -var_os="${var_os:-alpine}" -var_version="${var_version:-3.22}" -var_unprivileged="${var_unprivileged:-1}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - [[ -d /opt/komodo ]] || { - msg_error "No ${APP} Installation Found!" - exit 1 - } - - msg_info "Updating ${APP}" - COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1) - if [[ -z "$COMPOSE_FILE" ]]; then - msg_error "No valid compose file found in /opt/komodo!" - exit 1 - fi - COMPOSE_BASENAME=$(basename "$COMPOSE_FILE") - BACKUP_FILE="/opt/komodo/${COMPOSE_BASENAME}.bak_$(date +%Y%m%d_%H%M%S)" - cp "$COMPOSE_FILE" "$BACKUP_FILE" || { - msg_error "Failed to create backup of ${COMPOSE_BASENAME}!" - exit 1 - } - GITHUB_URL="https://raw.githubusercontent.com/moghtech/komodo/main/compose/${COMPOSE_BASENAME}" - if ! curl -fsSL "$GITHUB_URL" -o "$COMPOSE_FILE"; then - msg_error "Failed to download ${COMPOSE_BASENAME} from GitHub!" - mv "$BACKUP_FILE" "$COMPOSE_FILE" - exit 1 - fi - $STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d - msg_ok "Updated ${APP}" - 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}:9120${CL}" diff --git a/ct/alpine-tinyauth.sh b/ct/alpine-tinyauth.sh deleted file mode 100644 index bab0004b..00000000 --- a/ct/alpine-tinyauth.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2025 community-scripts ORG -# Author: Slaviša Arežina (tremor021) | Co-Author: Stavros (steveiliop56) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/steveiliop56/tinyauth - -APP="Alpine-Tinyauth" -var_tags="${var_tags:-alpine;auth}" -var_cpu="${var_cpu:-1}" -var_ram="${var_ram:-256}" -var_disk="${var_disk:-2}" -var_os="${var_os:-alpine}" -var_version="${var_version:-3.22}" -var_unprivileged="${var_unprivileged:-1}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - if [[ ! -d /opt/tinyauth ]]; then - msg_error "No ${APP} Installation Found!" - exit 1 - fi - - msg_info "Updating packages" - $STD apk -U upgrade - msg_ok "Updated packages" - - msg_info "Updating Tinyauth" - RELEASE=$(curl -s https://api.github.com/repos/steveiliop56/tinyauth/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') - - if [ "${RELEASE}" != "$(cat /opt/tinyauth_version.txt)" ] || [ ! -f /opt/tinyauth_version.txt ]; then - $STD service tinyauth stop - rm -f /opt/tinyauth/tinyauth - curl -fsSL "https://github.com/steveiliop56/tinyauth/releases/download/v${RELEASE}/tinyauth-amd64" -o /opt/tinyauth/tinyauth - chmod +x /opt/tinyauth/tinyauth - echo "${RELEASE}" >/opt/tinyauth_version.txt - msg_info "Restarting Tinyauth" - $STD service tinyauth start - msg_ok "Restarted Tinyauth" - msg_ok "Updated Tinyauth" - else - msg_ok "No update required. ${APP} is already at ${RELEASE}" - fi - exit 0 -} - -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}:3000${CL}" diff --git a/ct/stirling-pdf.sh b/ct/stirling-pdf.sh new file mode 100644 index 00000000..0c1ad5f1 --- /dev/null +++ b/ct/stirling-pdf.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://www.stirlingpdf.com/ + +APP="Stirling-PDF" +var_tags="${var_tags:-pdf-editor}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-2048}" +var_disk="${var_disk:-8}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +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/Stirling-PDF ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + msg_info "Updating ${APP}" + systemctl stop stirlingpdf + if [[ -n $(dpkg -l | grep -w ocrmypdf) ]] && [[ -z $(dpkg -l | grep -w qpdf) ]]; then + $STD apt-get remove -y ocrmypdf + $STD apt-get install -y qpdf + fi + RELEASE=$(curl -fsSL https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') + curl -fsSL "https://github.com/Stirling-Tools/Stirling-PDF/archive/refs/tags/v$RELEASE.tar.gz" -o $(basename "https://github.com/Stirling-Tools/Stirling-PDF/archive/refs/tags/v$RELEASE.tar.gz") + tar -xzf v$RELEASE.tar.gz + cd Stirling-PDF-$RELEASE + chmod +x ./gradlew + $STD ./gradlew build -x spotlessApply -x spotlessCheck -x test -x sonarqube + rm -rf /opt/Stirling-PDF/Stirling-PDF-*.jar + cp -r ./stirling-pdf/build/libs/*.jar /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar + cp -r scripts /opt/Stirling-PDF/ + cp -r pipeline /opt/Stirling-PDF/ + cp -r stirling-pdf/src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/ + cd ~ + rm -rf Stirling-PDF-$RELEASE v$RELEASE.tar.gz + ln -sf /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar /opt/Stirling-PDF/Stirling-PDF.jar + systemctl start stirlingpdf + msg_ok "Updated ${APP} to v$RELEASE" + 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}:8080${CL}" diff --git a/install/alpine-komodo-install.sh b/install/alpine-komodo-install.sh deleted file mode 100644 index e87bf687..00000000 --- a/install/alpine-komodo-install.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 community-scripts ORG -# Author: MickLesk (CanbiZ) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://komo.do/ - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apk add --no-cache ca-certificates openssl -msg_ok "Installed Dependencies" - -msg_info "Setup Docker Repository" -$STD apk add --no-cache docker docker-cli docker-compose openrc -msg_ok "Setup Docker Repository" - -msg_info "Enabling Docker Service" -$STD rc-update add docker boot -$STD service docker start -msg_ok "Enabled Docker Service" - -echo "${TAB3}Choose the database for Komodo installation:" -echo "${TAB3}1) MongoDB (recommended)" -echo "${TAB3}2) SQLite" -echo "${TAB3}3) PostgreSQL" -read -rp "${TAB3}Enter your choice (default: 1): " DB_CHOICE -DB_CHOICE=${DB_CHOICE:-1} - -case $DB_CHOICE in -1) - DB_COMPOSE_FILE="mongo.compose.yaml" - ;; -2) - DB_COMPOSE_FILE="sqlite.compose.yaml" - ;; -3) - DB_COMPOSE_FILE="postgres.compose.yaml" - ;; -*) - echo "Invalid choice. Defaulting to MongoDB." - DB_COMPOSE_FILE="mongo.compose.yaml" - ;; -esac - -mkdir -p /opt/komodo -cd /opt/komodo -curl -fsSL "https://raw.githubusercontent.com/moghtech/komodo/main/compose/$DB_COMPOSE_FILE" -o "$(basename "$DB_COMPOSE_FILE")" - -msg_info "Setup Komodo Environment" -curl -fsSL "https://raw.githubusercontent.com/moghtech/komodo/main/compose/compose.env" -o "/opt/komodo/compose.env" -DB_PASSWORD=$(openssl rand -base64 16 | tr -d '/+=') -PASSKEY=$(openssl rand -base64 24 | tr -d '/+=') -WEBHOOK_SECRET=$(openssl rand -base64 24 | tr -d '/+=') -JWT_SECRET=$(openssl rand -base64 24 | tr -d '/+=') - -sed -i "s/^KOMODO_DB_USERNAME=.*/KOMODO_DB_USERNAME=komodo_admin/" /opt/komodo/compose.env -sed -i "s/^KOMODO_DB_PASSWORD=.*/KOMODO_DB_PASSWORD=${DB_PASSWORD}/" /opt/komodo/compose.env -sed -i "s/^KOMODO_PASSKEY=.*/KOMODO_PASSKEY=${PASSKEY}/" /opt/komodo/compose.env -sed -i "s/^KOMODO_WEBHOOK_SECRET=.*/KOMODO_WEBHOOK_SECRET=${WEBHOOK_SECRET}/" /opt/komodo/compose.env -sed -i "s/^KOMODO_JWT_SECRET=.*/KOMODO_JWT_SECRET=${JWT_SECRET}/" /opt/komodo/compose.env -msg_ok "Setup Komodo Environment" - -msg_info "Initialize Komodo" -$STD docker compose -p komodo -f "/opt/komodo/$DB_COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d -msg_ok "Initialized Komodo" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apk cache clean -msg_ok "Cleaned" diff --git a/install/alpine-tinyauth-install.sh b/install/alpine-tinyauth-install.sh deleted file mode 100644 index 9aea59a6..00000000 --- a/install/alpine-tinyauth-install.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 community-scripts ORG -# Author: Slaviša Arežina (tremor021) | Co-Author: Stavros (steveiliop56) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/steveiliop56/tinyauth - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apk add --no-cache curl openssl apache2-utils -msg_ok "Installed Dependencies" - -msg_info "Installing Tinyauth" -mkdir -p /opt/tinyauth - -RELEASE=$(curl -s https://api.github.com/repos/steveiliop56/tinyauth/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -curl -fsSL "https://github.com/steveiliop56/tinyauth/releases/download/v${RELEASE}/tinyauth-amd64" -o /opt/tinyauth/tinyauth -chmod +x /opt/tinyauth/tinyauth - -PASSWORD=$(openssl rand -base64 8 | tr -dc 'a-zA-Z0-9' | head -c 8) -USER=$(htpasswd -Bbn "tinyauth" "${PASSWORD}") - -cat < /opt/tinyauth/credentials.txt -Tinyauth Credentials -Username: tinyauth -Password: ${PASSWORD} -EOF - -echo "${RELEASE}" >/opt/tinyauth_version.txt -msg_ok "Installed Tinyauth" - -read -p "${TAB3}Enter your Tinyauth subdomain (e.g. https://tinyauth.example.com): " app_url - -msg_info "Creating Tinyauth Service" -SECRET=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 32) - -cat </opt/tinyauth/.env -SECRET=${SECRET} -USERS=${USER} -APP_URL=${app_url} -EOF - -sed -i -e 's/\$/\$\$/g' /opt/tinyauth/.env - -cat <<'EOF' >/etc/init.d/tinyauth -#!/sbin/openrc-run -description="Tinyauth Service" - -command="/opt/tinyauth/tinyauth" -directory="/opt/tinyauth" -command_user="root" -command_background="true" -pidfile="/var/run/tinyauth.pid" - -start_pre() { - if [ -f "/opt/tinyauth/.env" ]; then - while IFS= read -r line || [ -n "$line" ]; do - [ -z "$line" ] && continue - case "$line" in - '#'*) - continue - ;; - esac - export "$line" - done < "/opt/tinyauth/.env" - fi -} - -depend() { - use net -} -EOF - -chmod +x /etc/init.d/tinyauth -$STD rc-update add tinyauth default -msg_ok "Enabled Tinyauth Service" - -msg_info "Starting Tinyauth" -$STD service tinyauth start -msg_ok "Started Tinyauth" - -motd_ssh -customize diff --git a/install/npmplus-install.sh b/install/npmplus-install.sh deleted file mode 100644 index ef355bc0..00000000 --- a/install/npmplus-install.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 community-scripts ORG -# Author: MickLesk (CanbiZ) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/ZoeyVid/NPMplus - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apk add \ - tzdata \ - gawk \ - yq -msg_ok "Installed Dependencies" - -msg_info "Installing Docker & Compose" -$STD apk add docker -$STD rc-service docker start -$STD rc-update add docker default - -get_latest_release() { - curl -fsSL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 -} -DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") -DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} -mkdir -p $DOCKER_CONFIG/cli-plugins -curl -fsSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose -chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose -msg_ok "Installed Docker & Compose" - -msg_info "Fetching NPMplus" -cd /opt -curl -fsSL "https://raw.githubusercontent.com/ZoeyVid/NPMplus/refs/heads/develop/compose.yaml" -o compose.yaml -msg_ok "Fetched NPMplus" - -attempts=0 -while true; do - read -r -p "${TAB3}Enter your TZ Identifier (e.g., Europe/Berlin): " TZ_INPUT - if validate_tz "$TZ_INPUT"; then - break - fi - msg_error "Invalid timezone! Please enter a valid TZ identifier." - - attempts=$((attempts + 1)) - if [[ "$attempts" -ge 3 ]]; then - msg_error "Maximum attempts reached. Exiting." - exit 1 - fi -done - -read -r -p "${TAB3}Enter your ACME Email: " ACME_EMAIL_INPUT - -yq -i " - .services.npmplus.environment |= - (map(select(. != \"TZ=*\" and . != \"ACME_EMAIL=*\")) + - [\"TZ=$TZ_INPUT\", \"ACME_EMAIL=$ACME_EMAIL_INPUT\"]) -" /opt/compose.yaml - -msg_info "Building and Starting NPMplus (Patience)" -$STD docker compose up -d -CONTAINER_ID="" -for i in {1..60}; do - CONTAINER_ID=$(docker ps --filter "name=npmplus" --format "{{.ID}}") - if [[ -n "$CONTAINER_ID" ]]; then - STATUS=$(docker inspect --format '{{.State.Health.Status}}' "$CONTAINER_ID" 2>/dev/null || echo "starting") - if [[ "$STATUS" == "healthy" ]]; then - msg_ok "NPMplus is running and healthy" - break - elif [[ "$STATUS" == "unhealthy" ]]; then - msg_error "NPMplus container is unhealthy! Check logs." - docker logs "$CONTAINER_ID" - exit 1 - fi - fi - sleep 2 - [[ $i -eq 60 ]] && msg_error "NPMplus container did not become healthy within 120s." && docker logs "$CONTAINER_ID" && exit 1 -done -msg_ok "Builded and started NPMplus" - -motd_ssh -customize - -msg_info "Retrieving Default Login (Patience)" -LOGFILE="/tmp/npmplus.log" -docker logs "$CONTAINER_ID" &>"$LOGFILE" & - -PASSWORD_FOUND=0 -for i in {1..60}; do - if grep -q "Creating a new user:" "$LOGFILE"; then - PASSWORD_LINE=$(grep "Creating a new user:" "$LOGFILE" | head -n1) - PASSWORD=$(echo "$PASSWORD_LINE" | awk -F 'password: ' '{print $2}') - if [[ -n "$PASSWORD" ]]; then - echo -e "username: admin@example.org\npassword: $PASSWORD" >/opt/.npm_pwd - msg_ok "Saved default login to /opt/.npm_pwd" - PASSWORD_FOUND=1 - break - fi - fi - sleep 2 -done - -if [[ $PASSWORD_FOUND -eq 0 ]]; then - msg_error "Could not retrieve default login after 60 seconds." - echo -e "\nYou can manually try:\n docker logs $CONTAINER_ID | grep 'Creating a new user:'\n" -fi - -rm -f "$LOGFILE" diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh new file mode 100644 index 00000000..c2fcf58a --- /dev/null +++ b/install/stirling-pdf-install.sh @@ -0,0 +1,154 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://www.stirlingpdf.com/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y \ + git \ + automake \ + autoconf \ + libtool \ + libleptonica-dev \ + pkg-config \ + zlib1g-dev \ + make \ + g++ \ + unpaper \ + qpdf \ + poppler-utils +msg_ok "Installed Dependencies" + +msg_info "Installing LibreOffice Components" +$STD apt-get install -y \ + libreoffice-writer \ + libreoffice-calc \ + libreoffice-impress \ + libreoffice-core \ + libreoffice-common \ + libreoffice-base-core \ + python3-uno +msg_ok "Installed LibreOffice Components" + +msg_info "Installing Python Dependencies" +$STD apt-get install -y \ + python3 \ + python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED +$STD pip3 install \ + uno \ + opencv-python-headless \ + unoconv \ + pngquant \ + WeasyPrint +msg_ok "Installed Python Dependencies" + +msg_info "Installing Azul Zulu" +curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xB1998361219BD9C9" -o "/etc/apt/trusted.gpg.d/zulu-repo.asc" +curl -fsSL "https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb" -o "/zulu-repo_1.0.0-3_all.deb" +$STD dpkg -i zulu-repo_1.0.0-3_all.deb +$STD apt-get update +$STD apt-get -y install zulu17-jdk +msg_ok "Installed Azul Zulu" + +msg_info "Installing JBIG2" +$STD git clone https://github.com/agl/jbig2enc /opt/jbig2enc +cd /opt/jbig2enc +$STD bash ./autogen.sh +$STD bash ./configure +$STD make +$STD make install +msg_ok "Installed JBIG2" + +msg_info "Installing Language Packs (Patience)" +$STD apt-get install -y 'tesseract-ocr-*' +msg_ok "Installed Language Packs" + +msg_info "Installing Stirling-PDF (Additional Patience)" +RELEASE=$(curl -fsSL https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +curl -fsSL "https://github.com/Stirling-Tools/Stirling-PDF/archive/refs/tags/v${RELEASE}.tar.gz" -o "v${RELEASE}.tar.gz" +tar -xzf v${RELEASE}.tar.gz +cd Stirling-PDF-$RELEASE +chmod +x ./gradlew +$STD ./gradlew build -x spotlessApply -x spotlessCheck -x test -x sonarqube +mkdir -p /opt/Stirling-PDF +touch /opt/Stirling-PDF/.env +mv ./stirling-pdf/build/libs/*.jar /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar +mv scripts /opt/Stirling-PDF/ +mv pipeline /opt/Stirling-PDF/ +mv stirling-pdf/src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/ +ln -s /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar /opt/Stirling-PDF/Stirling-PDF.jar +ln -s /usr/share/tesseract-ocr/5/tessdata/ /usr/share/tessdata +msg_ok "Installed Stirling-PDF" + +msg_info "Creating Service" +# Create LibreOffice listener service +cat </etc/systemd/system/libreoffice-listener.service +[Unit] +Description=LibreOffice Headless Listener Service +After=network.target + +[Service] +Type=simple +User=root +Group=root +ExecStart=/usr/lib/libreoffice/program/soffice --headless --invisible --nodefault --nofirststartwizard --nolockcheck --nologo --accept="socket,host=127.0.0.1,port=2002;urp;StarOffice.ComponentContext" +Restart=always + +[Install] +WantedBy=multi-user.target +EOF + +# Set up environment variables +cat </opt/Stirling-PDF/.env +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/libreoffice/program +UNO_PATH=/usr/lib/libreoffice/program +PYTHONPATH=/usr/lib/python3/dist-packages:/usr/lib/libreoffice/program +LD_LIBRARY_PATH=/usr/lib/libreoffice/program +EOF + +cat </etc/systemd/system/stirlingpdf.service +[Unit] +Description=Stirling-PDF service +After=syslog.target network.target libreoffice-listener.service +Requires=libreoffice-listener.service + +[Service] +SuccessExitStatus=143 +Type=simple +User=root +Group=root +EnvironmentFile=/opt/Stirling-PDF/.env +WorkingDirectory=/opt/Stirling-PDF +ExecStart=/usr/bin/java -jar Stirling-PDF.jar +ExecStop=/bin/kill -15 %n +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target +EOF + +# Enable and start services +systemctl enable -q --now libreoffice-listener +systemctl enable -q --now stirlingpdf +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -rf v${RELEASE}.tar.gz /zulu-repo_1.0.0-3_all.deb +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 11347f128ca98f81e4b85ba84a4985360f08e369 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 05:59:25 +0000 Subject: [PATCH 221/463] Update .app files (#690) Co-authored-by: GitHub Actions --- ct/headers/alpine-komodo | 6 ------ ct/headers/alpine-tinyauth | 6 ------ ct/headers/stirling-pdf | 6 ++++++ 3 files changed, 6 insertions(+), 12 deletions(-) delete mode 100644 ct/headers/alpine-komodo delete mode 100644 ct/headers/alpine-tinyauth create mode 100644 ct/headers/stirling-pdf diff --git a/ct/headers/alpine-komodo b/ct/headers/alpine-komodo deleted file mode 100644 index b945cc1b..00000000 --- a/ct/headers/alpine-komodo +++ /dev/null @@ -1,6 +0,0 @@ - ___ __ _ __ __ __ - / | / /___ (_)___ ___ / //_/___ ____ ___ ____ ____/ /___ - / /| | / / __ \/ / __ \/ _ \______/ ,< / __ \/ __ `__ \/ __ \/ __ / __ \ - / ___ |/ / /_/ / / / / / __/_____/ /| / /_/ / / / / / / /_/ / /_/ / /_/ / -/_/ |_/_/ .___/_/_/ /_/\___/ /_/ |_\____/_/ /_/ /_/\____/\__,_/\____/ - /_/ diff --git a/ct/headers/alpine-tinyauth b/ct/headers/alpine-tinyauth deleted file mode 100644 index 9fff055f..00000000 --- a/ct/headers/alpine-tinyauth +++ /dev/null @@ -1,6 +0,0 @@ - ___ __ _ _______ __ __ - / | / /___ (_)___ ___ /_ __(_)___ __ ______ ___ __/ /_/ /_ - / /| | / / __ \/ / __ \/ _ \______/ / / / __ \/ / / / __ `/ / / / __/ __ \ - / ___ |/ / /_/ / / / / / __/_____/ / / / / / / /_/ / /_/ / /_/ / /_/ / / / -/_/ |_/_/ .___/_/_/ /_/\___/ /_/ /_/_/ /_/\__, /\__,_/\__,_/\__/_/ /_/ - /_/ /____/ diff --git a/ct/headers/stirling-pdf b/ct/headers/stirling-pdf new file mode 100644 index 00000000..1b7775bb --- /dev/null +++ b/ct/headers/stirling-pdf @@ -0,0 +1,6 @@ + _____ __ _ ___ ____ ____ ______ + / ___// /_(_)____/ (_)___ ____ _ / __ \/ __ \/ ____/ + \__ \/ __/ / ___/ / / __ \/ __ `/_____/ /_/ / / / / /_ + ___/ / /_/ / / / / / / / / /_/ /_____/ ____/ /_/ / __/ +/____/\__/_/_/ /_/_/_/ /_/\__, / /_/ /_____/_/ + /____/ From d62311e2406ccce106edb332ff72d0c86d3ce876 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 08:34:17 +0200 Subject: [PATCH 222/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 56 ++++++++++++++++----------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index c2fcf58a..23846ac8 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -15,7 +15,6 @@ update_os msg_info "Installing Dependencies (Patience)" $STD apt-get install -y \ - git \ automake \ autoconf \ libtool \ @@ -29,6 +28,19 @@ $STD apt-get install -y \ poppler-utils msg_ok "Installed Dependencies" +PYTHON_VERSION="3.12" setup_uv +JAVA_VERSION="21" setup_java + +read -r -p "Do you want to Stirling-PDF with Login (Default = without Login)? [Y/n] " response +response=${response,,} # Convert to lowercase +if [[ "$response" == "y" || "$response" == "yes" || -z "$response" ]]; then + fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF-with-login.jar" + mv Stirling-PDF-with-login.jar /opt/Stirling-PDF/Stirling-PDF.jar + touch ~/.Stirling-PDF-login +else + fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF.jar" +fi + msg_info "Installing LibreOffice Components" $STD apt-get install -y \ libreoffice-writer \ @@ -37,32 +49,23 @@ $STD apt-get install -y \ libreoffice-core \ libreoffice-common \ libreoffice-base-core \ + unoconv \ + pngquant \ + weasyprint \ python3-uno msg_ok "Installed LibreOffice Components" -msg_info "Installing Python Dependencies" -$STD apt-get install -y \ - python3 \ - python3-pip -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED -$STD pip3 install \ - uno \ - opencv-python-headless \ - unoconv \ - pngquant \ - WeasyPrint -msg_ok "Installed Python Dependencies" - -msg_info "Installing Azul Zulu" -curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xB1998361219BD9C9" -o "/etc/apt/trusted.gpg.d/zulu-repo.asc" -curl -fsSL "https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb" -o "/zulu-repo_1.0.0-3_all.deb" -$STD dpkg -i zulu-repo_1.0.0-3_all.deb -$STD apt-get update -$STD apt-get -y install zulu17-jdk -msg_ok "Installed Azul Zulu" +$STD uv venv /opt/.venv +$STD uv pip install --upgrade pip +$STD uv pip install \ + opencv-python-headless +ln -sf /opt/.venv/bin/python3 /usr/local/bin/python3 +ln -sf /opt/.venv/bin/pip /usr/local/bin/pip msg_info "Installing JBIG2" -$STD git clone https://github.com/agl/jbig2enc /opt/jbig2enc +$STD curl -fsSL -o /tmp/jbig2enc.tar.gz https://github.com/agl/jbig2enc/archive/refs/tags/0.30.tar.gz +mkdir -p /opt/jbig2enc +tar -xzf /tmp/jbig2enc.tar.gz -C /opt/jbig2enc --strip-components=1 cd /opt/jbig2enc $STD bash ./autogen.sh $STD bash ./configure @@ -75,13 +78,9 @@ $STD apt-get install -y 'tesseract-ocr-*' msg_ok "Installed Language Packs" msg_info "Installing Stirling-PDF (Additional Patience)" -RELEASE=$(curl -fsSL https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -curl -fsSL "https://github.com/Stirling-Tools/Stirling-PDF/archive/refs/tags/v${RELEASE}.tar.gz" -o "v${RELEASE}.tar.gz" -tar -xzf v${RELEASE}.tar.gz -cd Stirling-PDF-$RELEASE +cd /opt/Stirling-PDF chmod +x ./gradlew $STD ./gradlew build -x spotlessApply -x spotlessCheck -x test -x sonarqube -mkdir -p /opt/Stirling-PDF touch /opt/Stirling-PDF/.env mv ./stirling-pdf/build/libs/*.jar /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar mv scripts /opt/Stirling-PDF/ @@ -92,7 +91,6 @@ ln -s /usr/share/tesseract-ocr/5/tessdata/ /usr/share/tessdata msg_ok "Installed Stirling-PDF" msg_info "Creating Service" -# Create LibreOffice listener service cat </etc/systemd/system/libreoffice-listener.service [Unit] Description=LibreOffice Headless Listener Service @@ -148,7 +146,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf v${RELEASE}.tar.gz /zulu-repo_1.0.0-3_all.deb +rm -f /tmp/jbig2enc.tar.gz $STD apt-get -y autoremove $STD apt-get -y autoclean msg_ok "Cleaned" From 1bc047cd8396364f7359a240438c90e1377bacf4 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 08:37:31 +0200 Subject: [PATCH 223/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index 23846ac8..9d783654 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -24,6 +24,7 @@ $STD apt-get install -y \ make \ g++ \ unpaper \ + fonts-urw-base35 \ qpdf \ poppler-utils msg_ok "Installed Dependencies" @@ -58,7 +59,9 @@ msg_ok "Installed LibreOffice Components" $STD uv venv /opt/.venv $STD uv pip install --upgrade pip $STD uv pip install \ - opencv-python-headless + opencv-python-headless \ + ocrmypdf \ pillow \ + pdf2image ln -sf /opt/.venv/bin/python3 /usr/local/bin/python3 ln -sf /opt/.venv/bin/pip /usr/local/bin/pip From 05bd7e83753b013bd358e75797ca99a0fc1ba2ca Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 08:39:03 +0200 Subject: [PATCH 224/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index 9d783654..8bc4942e 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -60,8 +60,10 @@ $STD uv venv /opt/.venv $STD uv pip install --upgrade pip $STD uv pip install \ opencv-python-headless \ - ocrmypdf \ pillow \ - pdf2image + ocrmypdf \ + pillow \ + pdf2image \ + unoserver ln -sf /opt/.venv/bin/python3 /usr/local/bin/python3 ln -sf /opt/.venv/bin/pip /usr/local/bin/pip @@ -88,11 +90,17 @@ touch /opt/Stirling-PDF/.env mv ./stirling-pdf/build/libs/*.jar /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar mv scripts /opt/Stirling-PDF/ mv pipeline /opt/Stirling-PDF/ +mkdir -p /usr/share/fonts/opentype/noto/ mv stirling-pdf/src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/ + ln -s /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar /opt/Stirling-PDF/Stirling-PDF.jar ln -s /usr/share/tesseract-ocr/5/tessdata/ /usr/share/tessdata msg_ok "Installed Stirling-PDF" +msg_info "Refreshing Font Cache" +$STD fc-cache -fv +msg_ok "Font Cache Updated" + msg_info "Creating Service" cat </etc/systemd/system/libreoffice-listener.service [Unit] From 7d5c3c18f414e0b4e992e7849d63fadb800f4add Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 08:48:34 +0200 Subject: [PATCH 225/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index 8bc4942e..093c9961 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -57,6 +57,7 @@ $STD apt-get install -y \ msg_ok "Installed LibreOffice Components" $STD uv venv /opt/.venv +export PATH="/opt/.venv/bin:$PATH" $STD uv pip install --upgrade pip $STD uv pip install \ opencv-python-headless \ @@ -83,20 +84,34 @@ $STD apt-get install -y 'tesseract-ocr-*' msg_ok "Installed Language Packs" msg_info "Installing Stirling-PDF (Additional Patience)" -cd /opt/Stirling-PDF -chmod +x ./gradlew -$STD ./gradlew build -x spotlessApply -x spotlessCheck -x test -x sonarqube -touch /opt/Stirling-PDF/.env -mv ./stirling-pdf/build/libs/*.jar /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar -mv scripts /opt/Stirling-PDF/ -mv pipeline /opt/Stirling-PDF/ mkdir -p /usr/share/fonts/opentype/noto/ -mv stirling-pdf/src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/ ln -s /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar /opt/Stirling-PDF/Stirling-PDF.jar ln -s /usr/share/tesseract-ocr/5/tessdata/ /usr/share/tessdata msg_ok "Installed Stirling-PDF" +msg_info "Creating Environment Variables" +cat </opt/Stirling-PDF/.env +# Java tuning +JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" +JAVA_CUSTOM_OPTS="" + +# LibreOffice +UNO_PATH=/usr/lib/libreoffice/program +URE_BOOTSTRAP=file:///usr/lib/libreoffice/program/fundamentalrc +PYTHONPATH=/usr/lib/libreoffice/program:/opt/.venv/lib/python3.12/site-packages +LD_LIBRARY_PATH=/usr/lib/libreoffice/program + +STIRLING_TEMPFILES_DIRECTORY=/tmp/stirling-pdf +TMPDIR=/tmp/stirling-pdf +TEMP=/tmp/stirling-pdf +TMP=/tmp/stirling-pdf + +# Paths +PATH=/opt/.venv/bin:/usr/lib/libreoffice/program:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +EOF +msg_ok "Created Environment Variables" + msg_info "Refreshing Font Cache" $STD fc-cache -fv msg_ok "Font Cache Updated" From 3eba4d1c83e67cc9524a23d6f773a0556face6df Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 08:56:26 +0200 Subject: [PATCH 226/463] filename --- install/stirling-pdf-install.sh | 4 ++-- misc/tools.func | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index 093c9961..e89634f2 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -35,11 +35,11 @@ JAVA_VERSION="21" setup_java read -r -p "Do you want to Stirling-PDF with Login (Default = without Login)? [Y/n] " response response=${response,,} # Convert to lowercase if [[ "$response" == "y" || "$response" == "yes" || -z "$response" ]]; then - fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF-with-login.jar" + USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF-with-login.jar" mv Stirling-PDF-with-login.jar /opt/Stirling-PDF/Stirling-PDF.jar touch ~/.Stirling-PDF-login else - fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF.jar" + USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF.jar" fi msg_info "Installing LibreOffice Components" diff --git a/misc/tools.func b/misc/tools.func index c354cff7..eb335a79 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -925,7 +925,7 @@ function fetch_and_deploy_gh_release() { } mkdir -p "$target" - if [[ "$filename" == *.zip ]]; then + if [[ "$filename" == *.zip ]]; then if ! command -v unzip &>/dev/null; then $STD apt-get install -y unzip fi @@ -986,7 +986,12 @@ function fetch_and_deploy_gh_release() { filename="${asset_url##*/}" mkdir -p "$target" - curl $download_timeout -fsSL -o "$target/$app" "$asset_url" || { + + local use_filename="${USE_ORIGINAL_FILENAME:-false}" + local target_file="$app" + [[ "$use_filename" == "true" ]] && target_file="$filename" + + curl $download_timeout -fsSL -o "$target/$target_file" "$asset_url" || { msg_error "Download failed: $asset_url" rm -rf "$tmpdir" return 1 From e2abf4f20408e6db5747336ff112e1526d3ed4f9 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 09:10:10 +0200 Subject: [PATCH 227/463] fix chmod --- misc/tools.func | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/misc/tools.func b/misc/tools.func index eb335a79..7957760b 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -997,7 +997,9 @@ function fetch_and_deploy_gh_release() { return 1 } - chmod +x "$target/$app" + if [[ "$chmod_target" != *.jar && -f "$target/$chmod_target" ]]; then + chmod +x "$target/$chmod_target" + fi else msg_error "Unknown mode: $mode" From e2b07acee6dbb9cde05e705464489ab21567751e Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 09:26:34 +0200 Subject: [PATCH 228/463] Update tools.func --- misc/tools.func | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 7957760b..b9a14593 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -997,8 +997,8 @@ function fetch_and_deploy_gh_release() { return 1 } - if [[ "$chmod_target" != *.jar && -f "$target/$chmod_target" ]]; then - chmod +x "$target/$chmod_target" + if [[ "$target_file" != *.jar && -f "$target/$target_file" ]]; then + chmod +x "$target/$target_file" fi else From 856faeefdd9f8dd46b48cbcc383be31c7dded1cc Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 09:42:56 +0200 Subject: [PATCH 229/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index e89634f2..c1c35fb2 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -84,10 +84,9 @@ $STD apt-get install -y 'tesseract-ocr-*' msg_ok "Installed Language Packs" msg_info "Installing Stirling-PDF (Additional Patience)" -mkdir -p /usr/share/fonts/opentype/noto/ +#mkdir -p /usr/share/fonts/opentype/noto/ -ln -s /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar /opt/Stirling-PDF/Stirling-PDF.jar -ln -s /usr/share/tesseract-ocr/5/tessdata/ /usr/share/tessdata +#ln -s /usr/share/tesseract-ocr/5/tessdata/ /usr/share/tessdata msg_ok "Installed Stirling-PDF" msg_info "Creating Environment Variables" From 0b461b001404db1254322e191cd362dfcbe5b0a0 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 09:48:34 +0200 Subject: [PATCH 230/463] Update build.func --- misc/build.func | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/build.func b/misc/build.func index 42d4260d..28af39b9 100644 --- a/misc/build.func +++ b/misc/build.func @@ -312,6 +312,8 @@ base_settings() { TAGS="${TAGS}${var_tags:-}" ENABLE_FUSE="${var_fuse:-$ENABLE_FUSE}" ENABLE_TUN="${var_tun:-$ENABLE_TUN}" + APT_CACHER="${var_apt_cacher:-$APT_CACHER}" + APT_CACHER_IP="${var_apt_cacher_ip:-$APT_CACHER_IP}" # Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts if [ -z "$var_os" ]; then From d6b604ecacf0656bcf5564b62f528eda751a2cd8 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 10:02:21 +0200 Subject: [PATCH 231/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index c1c35fb2..a09e7649 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -36,7 +36,7 @@ read -r -p "Do you want to Stirling-PDF with Login (Default = without Login)? [Y response=${response,,} # Convert to lowercase if [[ "$response" == "y" || "$response" == "yes" || -z "$response" ]]; then USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF-with-login.jar" - mv Stirling-PDF-with-login.jar /opt/Stirling-PDF/Stirling-PDF.jar + mv /opt/Stirling-PDF/Stirling-PDF-with-login.jar /opt/Stirling-PDF/Stirling-PDF.jar touch ~/.Stirling-PDF-login else USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF.jar" From dbc7dff9df8737acd30674dc33d0d7d84a7580c3 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 10:11:27 +0200 Subject: [PATCH 232/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index a09e7649..1d98b474 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -32,7 +32,7 @@ msg_ok "Installed Dependencies" PYTHON_VERSION="3.12" setup_uv JAVA_VERSION="21" setup_java -read -r -p "Do you want to Stirling-PDF with Login (Default = without Login)? [Y/n] " response +read -r -p "${TAB3}Do you want to Stirling-PDF with Login (Default = without Login)? [Y/n] " response response=${response,,} # Convert to lowercase if [[ "$response" == "y" || "$response" == "yes" || -z "$response" ]]; then USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF-with-login.jar" From 3338b00f224a8c8e145a691e74b3e7f43e8a07a6 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 10:33:09 +0200 Subject: [PATCH 233/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index 1d98b474..fbca7c76 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -34,10 +34,12 @@ JAVA_VERSION="21" setup_java read -r -p "${TAB3}Do you want to Stirling-PDF with Login (Default = without Login)? [Y/n] " response response=${response,,} # Convert to lowercase +login_mode="false" if [[ "$response" == "y" || "$response" == "yes" || -z "$response" ]]; then USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF-with-login.jar" mv /opt/Stirling-PDF/Stirling-PDF-with-login.jar /opt/Stirling-PDF/Stirling-PDF.jar touch ~/.Stirling-PDF-login + login_mode="true" else USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF.jar" fi @@ -96,6 +98,7 @@ JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:Ini JAVA_CUSTOM_OPTS="" # LibreOffice +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/libreoffice/program UNO_PATH=/usr/lib/libreoffice/program URE_BOOTSTRAP=file:///usr/lib/libreoffice/program/fundamentalrc PYTHONPATH=/usr/lib/libreoffice/program:/opt/.venv/lib/python3.12/site-packages @@ -109,6 +112,20 @@ TMP=/tmp/stirling-pdf # Paths PATH=/opt/.venv/bin:/usr/lib/libreoffice/program:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin EOF + +if [[ "$login_mode" == "true" ]]; then + cat <>/opt/Stirling-PDF/.env + +# activate Login +DISABLE_ADDITIONAL_FEATURES=false +SECURITY_ENABLELOGIN=true + +# login credentials +SECURITY_INITIALLOGIN_USERNAME=admin +SECURITY_INITIALLOGIN_PASSWORD=stirling +EOF +fi +msg_ok "Created Environment Variables" msg_ok "Created Environment Variables" msg_info "Refreshing Font Cache" @@ -132,14 +149,6 @@ Restart=always WantedBy=multi-user.target EOF -# Set up environment variables -cat </opt/Stirling-PDF/.env -PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/libreoffice/program -UNO_PATH=/usr/lib/libreoffice/program -PYTHONPATH=/usr/lib/python3/dist-packages:/usr/lib/libreoffice/program -LD_LIBRARY_PATH=/usr/lib/libreoffice/program -EOF - cat </etc/systemd/system/stirlingpdf.service [Unit] Description=Stirling-PDF service From 47635ff29c362fd2329b8ffddbcdd8effc27f147 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:56:55 +0200 Subject: [PATCH 234/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index fbca7c76..5c03ec58 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -54,10 +54,11 @@ $STD apt-get install -y \ libreoffice-base-core \ unoconv \ pngquant \ - weasyprint \ - python3-uno + weasyprint msg_ok "Installed LibreOffice Components" +msg_info "Installing Python Dependencies" +$STD apt-get install -y python3-pip python3-uno $STD uv venv /opt/.venv export PATH="/opt/.venv/bin:$PATH" $STD uv pip install --upgrade pip @@ -65,10 +66,11 @@ $STD uv pip install \ opencv-python-headless \ ocrmypdf \ pillow \ - pdf2image \ - unoserver + pdf2image +$STD pip3 install unoserver ln -sf /opt/.venv/bin/python3 /usr/local/bin/python3 ln -sf /opt/.venv/bin/pip /usr/local/bin/pip +msg_ok "Installed Python Dependencies" msg_info "Installing JBIG2" $STD curl -fsSL -o /tmp/jbig2enc.tar.gz https://github.com/agl/jbig2enc/archive/refs/tags/0.30.tar.gz From 06fc97a633eae46ecc4ddb671923f4dc4d0010ee Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 13:00:15 +0200 Subject: [PATCH 235/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index 5c03ec58..ec8ca640 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -58,6 +58,7 @@ $STD apt-get install -y \ msg_ok "Installed LibreOffice Components" msg_info "Installing Python Dependencies" +mkdir -p /tmp/stirling-pdf $STD apt-get install -y python3-pip python3-uno $STD uv venv /opt/.venv export PATH="/opt/.venv/bin:$PATH" @@ -173,9 +174,25 @@ RestartSec=10 WantedBy=multi-user.target EOF -# Enable and start services +cat </etc/systemd/system/unoserver.service +[Unit] +Description=UnoServer RPC Interface +After=libreoffice-listener.service +Requires=libreoffice-listener.service + +[Service] +Type=simple +ExecStart=/usr/local/bin/unoserver --port 2003 --interface 127.0.0.1 +Restart=always +EnvironmentFile=/opt/Stirling-PDF/.env + +[Install] +WantedBy=multi-user.target +EOF + systemctl enable -q --now libreoffice-listener systemctl enable -q --now stirlingpdf +systemctl enable -q --now unoserver msg_ok "Created Service" motd_ssh From c429d8a254c5d11bfa86a65425742ebb874314bb Mon Sep 17 00:00:00 2001 From: tremor021 Date: Tue, 8 Jul 2025 13:34:01 +0200 Subject: [PATCH 236/463] Add libreoffice-java-common to LibreOffice component list --- install/stirling-pdf-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index ec8ca640..ac1c7137 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -52,6 +52,7 @@ $STD apt-get install -y \ libreoffice-core \ libreoffice-common \ libreoffice-base-core \ + libreoffice-java-common \ unoconv \ pngquant \ weasyprint From 495dc78d38f8ceaf5031896982bc3731f2ffcc56 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:04:51 +0200 Subject: [PATCH 237/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index ac1c7137..470bfa18 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -72,6 +72,7 @@ $STD uv pip install \ $STD pip3 install unoserver ln -sf /opt/.venv/bin/python3 /usr/local/bin/python3 ln -sf /opt/.venv/bin/pip /usr/local/bin/pip +ln -sf /opt/.venv/bin/unoconvert /usr/local/bin/unoconvert msg_ok "Installed Python Dependencies" msg_info "Installing JBIG2" @@ -102,7 +103,7 @@ JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:Ini JAVA_CUSTOM_OPTS="" # LibreOffice -PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/libreoffice/program +PATH=/opt/.venv/bin:/usr/lib/libreoffice/program:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin UNO_PATH=/usr/lib/libreoffice/program URE_BOOTSTRAP=file:///usr/lib/libreoffice/program/fundamentalrc PYTHONPATH=/usr/lib/libreoffice/program:/opt/.venv/lib/python3.12/site-packages From a2a9c0e1a005853756cf7dfafd5514f0ebd12905 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:22:22 +0200 Subject: [PATCH 238/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index 470bfa18..71b3e414 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -68,10 +68,11 @@ $STD uv pip install \ opencv-python-headless \ ocrmypdf \ pillow \ - pdf2image -$STD pip3 install unoserver + pdf2image \ + unoserver ln -sf /opt/.venv/bin/python3 /usr/local/bin/python3 ln -sf /opt/.venv/bin/pip /usr/local/bin/pip +ln -sf /opt/.venv/bin/unoserver /usr/local/bin/unoserver ln -sf /opt/.venv/bin/unoconvert /usr/local/bin/unoconvert msg_ok "Installed Python Dependencies" From 3171d2ff314a7276af0253d149fb72f835e12a8e Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 12:40:52 +0000 Subject: [PATCH 239/463] Update versions.json (#691) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 70 +++++++++++++----------------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 56687f7c..6199eddb 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,29 @@ [ + { + "name": "bunkerity/bunkerweb", + "version": "testing", + "date": "2025-07-08T11:44:35Z" + }, + { + "name": "mattermost/mattermost", + "version": "preview-v0.1", + "date": "2025-06-27T14:35:47Z" + }, + { + "name": "docker/compose", + "version": "v2.38.2", + "date": "2025-07-08T09:35:14Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2132", + "date": "2025-07-08T05:52:22Z" + }, + { + "name": "Checkmk/checkmk", + "version": "v2.4.0p7", + "date": "2025-07-08T05:51:08Z" + }, { "name": "ollama/ollama", "version": "v0.9.5", @@ -19,6 +44,11 @@ "version": "v1.0.1", "date": "2025-07-07T23:01:28Z" }, + { + "name": "keycloak/keycloak", + "version": "26.3.0", + "date": "2025-07-02T12:26:44Z" + }, { "name": "duplicati/duplicati", "version": "v2.1.0.122-2.1.0.122_canary_2025-07-07", @@ -49,11 +79,6 @@ "version": "250707-d28b3101e", "date": "2025-07-07T15:15:21Z" }, - { - "name": "Checkmk/checkmk", - "version": "v2.4.0p7-rc2", - "date": "2025-07-07T15:07:57Z" - }, { "name": "traccar/traccar", "version": "v6.8.1", @@ -89,16 +114,6 @@ "version": "v1.5.2", "date": "2025-05-11T16:40:55Z" }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2125", - "date": "2025-07-07T05:56:33Z" - }, - { - "name": "mattermost/mattermost", - "version": "preview-v0.1", - "date": "2025-06-27T14:35:47Z" - }, { "name": "MediaBrowser/Emby.Releases", "version": "4.9.1.2", @@ -214,11 +229,6 @@ "version": "v3.3.0", "date": "2025-06-12T06:54:48Z" }, - { - "name": "bunkerity/bunkerweb", - "version": "v1.6.2", - "date": "2025-07-04T15:21:18Z" - }, { "name": "emqx/emqx", "version": "e6.0.0-M1.202507-alpha.1", @@ -229,11 +239,6 @@ "version": "2.37.0", "date": "2025-07-04T14:49:43Z" }, - { - "name": "keycloak/keycloak", - "version": "26.3.0", - "date": "2025-07-02T12:26:44Z" - }, { "name": "Graylog2/graylog2-server", "version": "6.3.1", @@ -389,11 +394,6 @@ "version": "v2.32.0", "date": "2025-06-30T22:12:48Z" }, - { - "name": "docker/compose", - "version": "v2.38.1", - "date": "2025-06-30T20:07:35Z" - }, { "name": "jhuckaby/Cronicle", "version": "v0.9.81", @@ -483,15 +483,5 @@ "name": "AdguardTeam/AdGuardHome", "version": "v0.107.63", "date": "2025-06-26T14:34:19Z" - }, - { - "name": "node-red/node-red", - "version": "4.1.0-beta.2", - "date": "2025-06-26T14:23:26Z" - }, - { - "name": "gristlabs/grist-core", - "version": "v1.6.1", - "date": "2025-06-25T21:19:25Z" } ] From 166231769c3291165b16adc1e69b870ebcad576d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:43:14 +0200 Subject: [PATCH 240/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index 71b3e414..ace211ac 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -63,6 +63,7 @@ mkdir -p /tmp/stirling-pdf $STD apt-get install -y python3-pip python3-uno $STD uv venv /opt/.venv export PATH="/opt/.venv/bin:$PATH" +source /opt/.venv/bin/activate $STD uv pip install --upgrade pip $STD uv pip install \ opencv-python-headless \ @@ -70,6 +71,7 @@ $STD uv pip install \ pillow \ pdf2image \ unoserver +deactivate ln -sf /opt/.venv/bin/python3 /usr/local/bin/python3 ln -sf /opt/.venv/bin/pip /usr/local/bin/pip ln -sf /opt/.venv/bin/unoserver /usr/local/bin/unoserver From 99e7a7a0532b9d243c51dc556cea54d859daece9 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:50:31 +0200 Subject: [PATCH 241/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index ace211ac..a0e4a0a4 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -123,7 +123,6 @@ EOF if [[ "$login_mode" == "true" ]]; then cat <>/opt/Stirling-PDF/.env - # activate Login DISABLE_ADDITIONAL_FEATURES=false SECURITY_ENABLELOGIN=true @@ -134,7 +133,6 @@ SECURITY_INITIALLOGIN_PASSWORD=stirling EOF fi msg_ok "Created Environment Variables" -msg_ok "Created Environment Variables" msg_info "Refreshing Font Cache" $STD fc-cache -fv From afe3a97656e2acab11538d126615e3d5c3ec9d11 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 15:01:34 +0200 Subject: [PATCH 242/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index a0e4a0a4..1e44c4a2 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -32,7 +32,7 @@ msg_ok "Installed Dependencies" PYTHON_VERSION="3.12" setup_uv JAVA_VERSION="21" setup_java -read -r -p "${TAB3}Do you want to Stirling-PDF with Login (Default = without Login)? [Y/n] " response +read -r -p "${TAB3}Do you want to Stirling-PDF with Login (no/n = without Login)? [Y/n] " response response=${response,,} # Convert to lowercase login_mode="false" if [[ "$response" == "y" || "$response" == "yes" || -z "$response" ]]; then From 75bc4add5205b5adea286576e00f494dc6371918 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 15:01:45 +0200 Subject: [PATCH 243/463] Update stirling-pdf-install.sh --- install/stirling-pdf-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index 1e44c4a2..db7df659 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -32,7 +32,7 @@ msg_ok "Installed Dependencies" PYTHON_VERSION="3.12" setup_uv JAVA_VERSION="21" setup_java -read -r -p "${TAB3}Do you want to Stirling-PDF with Login (no/n = without Login)? [Y/n] " response +read -r -p "${TAB3}Do you want to Stirling-PDF with Login? (no/n = without Login) [Y/n] " response response=${response,,} # Convert to lowercase login_mode="false" if [[ "$response" == "y" || "$response" == "yes" || -z "$response" ]]; then From af9982536f7fe011b7516df0e05f6b85e3f4d19f Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 16:45:21 +0200 Subject: [PATCH 244/463] Update tools.func --- misc/tools.func | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index b9a14593..19ca7435 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -431,6 +431,12 @@ function setup_php() { fi local MODULE_LIST="php${PHP_VERSION}" + for pkg in $MODULE_LIST; do + if ! apt-cache show "$pkg" >/dev/null 2>&1; then + msg_error "Package not found: $pkg" + exit 1 + fi + done IFS=',' read -ra MODULES <<<"$COMBINED_MODULES" for mod in "${MODULES[@]}"; do MODULE_LIST+=" php${PHP_VERSION}-${mod}" @@ -439,7 +445,11 @@ function setup_php() { if [[ "$PHP_FPM" == "YES" ]]; then MODULE_LIST+=" php${PHP_VERSION}-fpm" fi - + if [[ "$PHP_APACHE" == "YES" ]]; then + $STD apt-get install -y apache2 + $STD systemctl restart apache2 || true + fi + if [[ "$PHP_APACHE" == "YES" ]] && [[ -n "$CURRENT_PHP" ]]; then if [[ -f /etc/apache2/mods-enabled/php${CURRENT_PHP}.load ]]; then $STD a2dismod php${CURRENT_PHP} || true @@ -647,9 +657,24 @@ function setup_mongodb() { DISTRO_ID=$(awk -F= '/^ID=/{ gsub(/"/,"",$2); print $2 }' /etc/os-release) DISTRO_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{ print $2 }' /etc/os-release) + # Check AVX support + if ! grep -qm1 'avx[^ ]*' /proc/cpuinfo; then + local major="${MONGO_VERSION%%.*}" + if ((major > 5)); then + msg_error "MongoDB ${MONGO_VERSION} requires AVX support, which is not available on this system." + return 1 + fi + fi + case "$DISTRO_ID" in - ubuntu) MONGO_BASE_URL="https://repo.mongodb.org/apt/ubuntu" ;; - debian) MONGO_BASE_URL="https://repo.mongodb.org/apt/debian" ;; + ubuntu) + MONGO_BASE_URL="https://repo.mongodb.org/apt/ubuntu" + REPO_COMPONENT="multiverse" + ;; + debian) + MONGO_BASE_URL="https://repo.mongodb.org/apt/debian" + REPO_COMPONENT="main" + ;; *) msg_error "Unsupported distribution: $DISTRO_ID" return 1 From b9ee77c181f23e51f50c0879f37731009c8e9c83 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 8 Jul 2025 16:51:10 +0200 Subject: [PATCH 245/463] Update ersatztv.sh --- ct/ersatztv.sh | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/ct/ersatztv.sh b/ct/ersatztv.sh index 381e1e17..7430fb8b 100644 --- a/ct/ersatztv.sh +++ b/ct/ersatztv.sh @@ -7,7 +7,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV APP="ErsatzTV" var_tags="${var_tags:-iptv}" -var_cpu="${var_cpu:-1}" +var_cpu="${var_cpu:-2}" var_ram="${var_ram:-1024}" var_disk="${var_disk:-5}" var_os="${var_os:-debian}" @@ -27,31 +27,17 @@ function update_script() { exit fi RELEASE=$(curl -fsSL https://api.github.com/repos/ErsatzTV/ErsatzTV/releases | grep -oP '"tag_name": "\K[^"]+' | head -n 1) - if [[ ! -f /opt/${APP}_version.txt && $(echo "x.x.x" >/opt/${APP}_version.txt) || "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + if [[ "${RELEASE}" != "$(cat ~/.ersatztv 2>/dev/null)" ]] || [[ ! -f ~/.ersatztv ]]; then msg_info "Stopping ErsatzTV" systemctl stop ersatzTV msg_ok "Stopped ErsatzTV" - msg_info "Updating ErsatzTV" - cp -R /opt/ErsatzTV/ ErsatzTV-backup - rm ErsatzTV-backup/ErsatzTV - rm -rf /opt/ErsatzTV - temp_file=$(mktemp) - curl -fsSL "https://github.com/ErsatzTV/ErsatzTV/releases/download/${RELEASE}/ErsatzTV-${RELEASE}-linux-x64.tar.gz" -o "$temp_file" - tar -xzf "$temp_file" - mv ErsatzTV-${RELEASE}-linux-x64 /opt/ErsatzTV - cp -R ErsatzTV-backup/* /opt/ErsatzTV/ - rm -rf ErsatzTV-backup - echo "${RELEASE}" >/opt/${APP}_version.txt - msg_ok "Updated ErsatzTV" + fetch_and_deploy_gh_release "ersatztv" "ErsatzTV/ErsatzTV" "prebuild" "latest" "/opt/ErsatzTV" "*linux-x64.tar.gz" msg_info "Starting ErsatzTV" systemctl start ersatzTV msg_ok "Started ErsatzTV" - msg_info "Cleaning Up" - rm -f ${temp_file} - msg_ok "Cleaned" msg_ok "Updated Successfully" else msg_ok "No update required. ${APP} is already at ${RELEASE}" From 8ca40e8ce70a561d3766809c03f4a3302e0eaa92 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Wed, 9 Jul 2025 01:41:52 +0000 Subject: [PATCH 246/463] Update versions.json (#692) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 118 ++++++++++++++--------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 6199eddb..91eaff63 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,8 +1,63 @@ [ + { + "name": "henrygd/beszel", + "version": "v0.11.1", + "date": "2025-04-29T01:14:35Z" + }, + { + "name": "steveiliop56/tinyauth", + "version": "v3.4.1", + "date": "2025-06-11T07:53:44Z" + }, + { + "name": "Prowlarr/Prowlarr", + "version": "v1.37.0.5076", + "date": "2025-06-04T11:04:53Z" + }, + { + "name": "Radarr/Radarr", + "version": "v5.26.2.10099", + "date": "2025-06-11T20:10:39Z" + }, + { + "name": "ipfs/kubo", + "version": "v0.35.0", + "date": "2025-05-21T18:00:32Z" + }, + { + "name": "rcourtman/Pulse", + "version": "v3.40.1", + "date": "2025-07-08T21:06:54Z" + }, + { + "name": "grokability/snipe-it", + "version": "v8.1.18", + "date": "2025-07-08T20:36:37Z" + }, + { + "name": "Stirling-Tools/Stirling-PDF", + "version": "v1.0.2", + "date": "2025-07-08T19:14:31Z" + }, + { + "name": "TwiN/gatus", + "version": "v5.20.0", + "date": "2025-07-08T16:27:11Z" + }, + { + "name": "fuma-nama/fumadocs", + "version": "create-fumadocs-app@15.6.2", + "date": "2025-07-08T14:26:05Z" + }, + { + "name": "jenkinsci/jenkins", + "version": "jenkins-2.518", + "date": "2025-07-08T13:52:55Z" + }, { "name": "bunkerity/bunkerweb", - "version": "testing", - "date": "2025-07-08T11:44:35Z" + "version": "v1.6.2", + "date": "2025-07-08T13:52:33Z" }, { "name": "mattermost/mattermost", @@ -26,24 +81,14 @@ }, { "name": "ollama/ollama", - "version": "v0.9.5", - "date": "2025-07-02T18:39:28Z" - }, - { - "name": "steveiliop56/tinyauth", - "version": "v3.4.1", - "date": "2025-06-11T07:53:44Z" + "version": "v0.9.6", + "date": "2025-07-08T01:26:29Z" }, { "name": "mongodb/mongo", "version": "r8.0.12-rc0", "date": "2025-07-07T23:35:35Z" }, - { - "name": "Stirling-Tools/Stirling-PDF", - "version": "v1.0.1", - "date": "2025-07-07T23:01:28Z" - }, { "name": "keycloak/keycloak", "version": "26.3.0", @@ -199,11 +244,6 @@ "version": "v4.3.0", "date": "2025-07-05T12:14:52Z" }, - { - "name": "fuma-nama/fumadocs", - "version": "fumadocs-openapi@9.0.18", - "date": "2025-07-05T09:36:45Z" - }, { "name": "theonedev/onedev", "version": "v11.11.4", @@ -339,11 +379,6 @@ "version": "1.2.35", "date": "2025-07-01T21:37:20Z" }, - { - "name": "TwiN/gatus", - "version": "v5.19.0", - "date": "2025-07-01T19:59:32Z" - }, { "name": "hivemq/hivemq-community-edition", "version": "2025.4", @@ -359,21 +394,11 @@ "version": "v0.57.0", "date": "2025-07-01T16:47:46Z" }, - { - "name": "jenkinsci/jenkins", - "version": "jenkins-2.517", - "date": "2025-07-01T16:08:23Z" - }, { "name": "element-hq/synapse", "version": "v1.133.0", "date": "2025-07-01T15:13:42Z" }, - { - "name": "rcourtman/Pulse", - "version": "v99.99.99", - "date": "2025-07-01T08:26:41Z" - }, { "name": "zabbix/zabbix", "version": "7.4.0", @@ -409,11 +434,6 @@ "version": "v7.4.4", "date": "2025-06-30T13:04:22Z" }, - { - "name": "grokability/snipe-it", - "version": "v8.1.17", - "date": "2025-06-30T11:26:27Z" - }, { "name": "PrivateBin/PrivateBin", "version": "1.7.8", @@ -463,25 +483,5 @@ "name": "netbox-community/netbox", "version": "v4.3.3", "date": "2025-06-26T18:42:56Z" - }, - { - "name": "apache/tika", - "version": "3.2.1-rc2", - "date": "2025-06-26T17:10:25Z" - }, - { - "name": "tailscale/tailscale", - "version": "v1.84.3", - "date": "2025-06-26T16:31:57Z" - }, - { - "name": "traefik/traefik", - "version": "v3.5.0-rc1", - "date": "2025-06-26T15:08:43Z" - }, - { - "name": "AdguardTeam/AdGuardHome", - "version": "v0.107.63", - "date": "2025-06-26T14:34:19Z" } ] From 20172bbaef68f77013de8b785c8d57966e34ffe7 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 9 Jul 2025 11:11:21 +0200 Subject: [PATCH 247/463] testing stirling --- ct/ersatztv.sh | 1 + install/stirling-pdf-install.sh | 19 ++++++------------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/ct/ersatztv.sh b/ct/ersatztv.sh index 7430fb8b..c1e477ac 100644 --- a/ct/ersatztv.sh +++ b/ct/ersatztv.sh @@ -32,6 +32,7 @@ function update_script() { systemctl stop ersatzTV msg_ok "Stopped ErsatzTV" + FFMPEG_VERSION="latest" FFMPEG_TYPE="medium" setup_ffmpeg fetch_and_deploy_gh_release "ersatztv" "ErsatzTV/ErsatzTV" "prebuild" "latest" "/opt/ErsatzTV" "*linux-x64.tar.gz" msg_info "Starting ErsatzTV" diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index db7df659..cbcb08ff 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -52,6 +52,7 @@ $STD apt-get install -y \ libreoffice-core \ libreoffice-common \ libreoffice-base-core \ + libreoffice-script-provider-python \ libreoffice-java-common \ unoconv \ pngquant \ @@ -60,7 +61,6 @@ msg_ok "Installed LibreOffice Components" msg_info "Installing Python Dependencies" mkdir -p /tmp/stirling-pdf -$STD apt-get install -y python3-pip python3-uno $STD uv venv /opt/.venv export PATH="/opt/.venv/bin:$PATH" source /opt/.venv/bin/activate @@ -69,13 +69,12 @@ $STD uv pip install \ opencv-python-headless \ ocrmypdf \ pillow \ - pdf2image \ - unoserver -deactivate + pdf2image + +$STD apt install -y python3-uno +$STD pip3 install --break-system-packages unoserver ln -sf /opt/.venv/bin/python3 /usr/local/bin/python3 ln -sf /opt/.venv/bin/pip /usr/local/bin/pip -ln -sf /opt/.venv/bin/unoserver /usr/local/bin/unoserver -ln -sf /opt/.venv/bin/unoconvert /usr/local/bin/unoconvert msg_ok "Installed Python Dependencies" msg_info "Installing JBIG2" @@ -93,12 +92,6 @@ msg_info "Installing Language Packs (Patience)" $STD apt-get install -y 'tesseract-ocr-*' msg_ok "Installed Language Packs" -msg_info "Installing Stirling-PDF (Additional Patience)" -#mkdir -p /usr/share/fonts/opentype/noto/ - -#ln -s /usr/share/tesseract-ocr/5/tessdata/ /usr/share/tessdata -msg_ok "Installed Stirling-PDF" - msg_info "Creating Environment Variables" cat </opt/Stirling-PDF/.env # Java tuning @@ -185,7 +178,7 @@ Requires=libreoffice-listener.service [Service] Type=simple -ExecStart=/usr/local/bin/unoserver --port 2003 --interface 127.0.0.1 +ExecStart=/usr/bin/python3 -m unoserver --port 2003 --interface 127.0.0.1 Restart=always EnvironmentFile=/opt/Stirling-PDF/.env From d26ca653974e09f572fb431896a745343d8310f8 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 9 Jul 2025 11:29:08 +0200 Subject: [PATCH 248/463] final --- install/stirling-pdf-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index cbcb08ff..5a87a57a 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -71,7 +71,7 @@ $STD uv pip install \ pillow \ pdf2image -$STD apt install -y python3-uno +$STD apt-get install -y python3-uno python3-pip $STD pip3 install --break-system-packages unoserver ln -sf /opt/.venv/bin/python3 /usr/local/bin/python3 ln -sf /opt/.venv/bin/pip /usr/local/bin/pip @@ -178,7 +178,7 @@ Requires=libreoffice-listener.service [Service] Type=simple -ExecStart=/usr/bin/python3 -m unoserver --port 2003 --interface 127.0.0.1 +ExecStart=/usr/local/bin/unoserver --port 2003 --interface 127.0.0.1 Restart=always EnvironmentFile=/opt/Stirling-PDF/.env From 99530262074be25a9ede7dae6b725b2f857c7f48 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 9 Jul 2025 13:14:00 +0200 Subject: [PATCH 249/463] Update tools.func --- misc/tools.func | 52 +++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 19ca7435..2b8a2a5b 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -449,7 +449,7 @@ function setup_php() { $STD apt-get install -y apache2 $STD systemctl restart apache2 || true fi - + if [[ "$PHP_APACHE" == "YES" ]] && [[ -n "$CURRENT_PHP" ]]; then if [[ -f /etc/apache2/mods-enabled/php${CURRENT_PHP}.load ]]; then $STD a2dismod php${CURRENT_PHP} || true @@ -914,7 +914,7 @@ function fetch_and_deploy_gh_release() { } } - ### Prebuild Mode ### + ### Prebuild Mode ### elif [[ "$mode" == "prebuild" ]]; then local pattern="${6%\"}" pattern="${pattern#\"}" @@ -933,7 +933,6 @@ function fetch_and_deploy_gh_release() { break ;; esac - done [[ -z "$asset_url" ]] && { @@ -949,39 +948,42 @@ function fetch_and_deploy_gh_release() { return 1 } + local unpack_tmp + unpack_tmp=$(mktemp -d) mkdir -p "$target" + if [[ "$filename" == *.zip ]]; then if ! command -v unzip &>/dev/null; then $STD apt-get install -y unzip fi - - local top_level_entries - top_level_entries=$(unzip -l "$tmpdir/$filename" | awk '{print $4}' | grep -v '^$' | cut -d/ -f1 | sort -u) - - if [[ $(wc -l <<<"$top_level_entries") -eq 1 ]]; then - unzip -q "$tmpdir/$filename" -d "$tmpdir/unzip" - shopt -s dotglob nullglob - cp -r "$tmpdir/unzip/"* "$target/" - shopt -u dotglob nullglob - else - unzip -q "$tmpdir/$filename" -d "$target" - fi - + unzip -q "$tmpdir/$filename" -d "$unpack_tmp" elif [[ "$filename" == *.tar.* ]]; then - local top_level_entries - top_level_entries=$(tar -tf "$tmpdir/$filename" | cut -d/ -f1 | sort -u) - - if [[ $(wc -l <<<"$top_level_entries") -eq 1 ]]; then - tar --strip-components=1 -xf "$tmpdir/$filename" -C "$target" - else - tar -xf "$tmpdir/$filename" -C "$target" - fi + tar -xf "$tmpdir/$filename" -C "$unpack_tmp" else msg_error "Unsupported archive format: $filename" - rm -rf "$tmpdir" + rm -rf "$tmpdir" "$unpack_tmp" return 1 fi + local top_dirs + top_dirs=$(find "$unpack_tmp" -mindepth 1 -maxdepth 1 -type d | wc -l) + + if [[ "$top_dirs" -eq 1 ]]; then + # Strip leading folder + local inner_dir + inner_dir=$(find "$unpack_tmp" -mindepth 1 -maxdepth 1 -type d) + shopt -s dotglob nullglob + cp -r "$inner_dir"/* "$target/" + shopt -u dotglob nullglob + else + # Copy all contents + shopt -s dotglob nullglob + cp -r "$unpack_tmp"/* "$target/" + shopt -u dotglob nullglob + fi + + rm -rf "$unpack_tmp" + ### Singlefile Mode ### elif [[ "$mode" == "singlefile" ]]; then local pattern="${6%\"}" From ab2ccdd67e5b64d6ef3775c478c842c6b9abbba4 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Wed, 9 Jul 2025 12:41:29 +0000 Subject: [PATCH 250/463] Update versions.json (#694) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 110 ++++++++++++++++------------- 1 file changed, 60 insertions(+), 50 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 91eaff63..eba1ee34 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,54 @@ [ + { + "name": "crowdsecurity/crowdsec", + "version": "v1.6.9", + "date": "2025-06-17T11:54:50Z" + }, + { + "name": "element-hq/synapse", + "version": "v1.134.0rc1", + "date": "2025-07-09T11:33:33Z" + }, + { + "name": "n8n-io/n8n", + "version": "n8n@1.102.0", + "date": "2025-07-07T15:32:29Z" + }, + { + "name": "rclone/rclone", + "version": "v1.70.3", + "date": "2025-07-09T10:02:39Z" + }, + { + "name": "fuma-nama/fumadocs", + "version": "fumadocs-ui@15.6.3", + "date": "2025-07-09T09:28:42Z" + }, + { + "name": "cockpit-project/cockpit", + "version": "342", + "date": "2025-07-09T08:48:21Z" + }, + { + "name": "esphome/esphome", + "version": "2025.6.3", + "date": "2025-07-03T01:07:26Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2135", + "date": "2025-07-09T05:58:50Z" + }, + { + "name": "MediaBrowser/Emby.Releases", + "version": "4.9.1.2", + "date": "2025-06-26T22:08:00Z" + }, + { + "name": "NginxProxyManager/nginx-proxy-manager", + "version": "v2.14.5", + "date": "2025-07-09T04:41:02Z" + }, { "name": "henrygd/beszel", "version": "v0.11.1", @@ -39,16 +89,16 @@ "version": "v1.0.2", "date": "2025-07-08T19:14:31Z" }, + { + "name": "keycloak/keycloak", + "version": "26.3.0", + "date": "2025-07-02T12:26:44Z" + }, { "name": "TwiN/gatus", "version": "v5.20.0", "date": "2025-07-08T16:27:11Z" }, - { - "name": "fuma-nama/fumadocs", - "version": "create-fumadocs-app@15.6.2", - "date": "2025-07-08T14:26:05Z" - }, { "name": "jenkinsci/jenkins", "version": "jenkins-2.518", @@ -69,11 +119,6 @@ "version": "v2.38.2", "date": "2025-07-08T09:35:14Z" }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2132", - "date": "2025-07-08T05:52:22Z" - }, { "name": "Checkmk/checkmk", "version": "v2.4.0p7", @@ -89,11 +134,6 @@ "version": "r8.0.12-rc0", "date": "2025-07-07T23:35:35Z" }, - { - "name": "keycloak/keycloak", - "version": "26.3.0", - "date": "2025-07-02T12:26:44Z" - }, { "name": "duplicati/duplicati", "version": "v2.1.0.122-2.1.0.122_canary_2025-07-07", @@ -114,11 +154,6 @@ "version": "pmm-6401-v1.121.0", "date": "2025-07-07T16:16:13Z" }, - { - "name": "n8n-io/n8n", - "version": "n8n@1.100.0", - "date": "2025-06-23T12:48:35Z" - }, { "name": "photoprism/photoprism", "version": "250707-d28b3101e", @@ -159,11 +194,6 @@ "version": "v1.5.2", "date": "2025-05-11T16:40:55Z" }, - { - "name": "MediaBrowser/Emby.Releases", - "version": "4.9.1.2", - "date": "2025-06-26T22:08:00Z" - }, { "name": "firefly-iii/firefly-iii", "version": "v6.2.20", @@ -309,21 +339,11 @@ "version": "v3.2.1", "date": "2025-07-03T16:09:19Z" }, - { - "name": "cockpit-project/cockpit", - "version": "310.5", - "date": "2025-07-03T14:05:25Z" - }, { "name": "Dolibarr/dolibarr", "version": "18.0.7", "date": "2025-07-03T08:57:21Z" }, - { - "name": "esphome/esphome", - "version": "2025.6.3", - "date": "2025-07-03T01:07:26Z" - }, { "name": "actualbudget/actual", "version": "v25.7.1", @@ -394,11 +414,6 @@ "version": "v0.57.0", "date": "2025-07-01T16:47:46Z" }, - { - "name": "element-hq/synapse", - "version": "v1.133.0", - "date": "2025-07-01T15:13:42Z" - }, { "name": "zabbix/zabbix", "version": "7.4.0", @@ -409,11 +424,6 @@ "version": "v0.15.0-rc3", "date": "2025-07-01T04:09:37Z" }, - { - "name": "NginxProxyManager/nginx-proxy-manager", - "version": "v2.12.4", - "date": "2025-07-01T01:45:42Z" - }, { "name": "MagicMirrorOrg/MagicMirror", "version": "v2.32.0", @@ -464,11 +474,6 @@ "version": "version/2025.6.3", "date": "2025-06-27T14:01:06Z" }, - { - "name": "rclone/rclone", - "version": "v1.70.2", - "date": "2025-06-27T13:21:17Z" - }, { "name": "sabnzbd/sabnzbd", "version": "4.5.1", @@ -483,5 +488,10 @@ "name": "netbox-community/netbox", "version": "v4.3.3", "date": "2025-06-26T18:42:56Z" + }, + { + "name": "apache/tika", + "version": "3.2.1-rc2", + "date": "2025-06-26T17:10:25Z" } ] From 58104cc7431ddfe81a78763c8bf06ccac1c840d7 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 9 Jul 2025 15:24:54 +0200 Subject: [PATCH 251/463] test --- misc/build.func | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/misc/build.func b/misc/build.func index 28af39b9..23e99931 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1241,6 +1241,7 @@ EOF "Ollama" "FileFlows" "Open WebUI" + "Debian" ) is_vaapi_app=false @@ -1311,6 +1312,16 @@ EOF fi fi fi + if [ "$CT_TYPE" == "1" ] && [ "$is_vaapi_app" == "true" ]; then + if [[ -e /dev/dri/card0 ]]; then + echo "dev0: /dev/dri/card0,gid=44" >>"$LXC_CONFIG" + elif [[ -e /dev/dri/card1 ]]; then + echo "dev0: /dev/dri/card1,gid=44" >>"$LXC_CONFIG" + fi + if [[ -e /dev/dri/renderD128 ]]; then + echo "dev1: /dev/dri/renderD128,gid=104" >>"$LXC_CONFIG" + fi + fi # TUN device passthrough if [ "$ENABLE_TUN" == "yes" ]; then From 7c8cd943285c85e9700344f052dbd9cf1e96bd9d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 9 Jul 2025 15:27:32 +0200 Subject: [PATCH 252/463] Update build.func --- misc/build.func | 55 +++++++++++++++---------------------------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/misc/build.func b/misc/build.func index 23e99931..d4f94e84 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1265,52 +1265,31 @@ EOF read -rp "➤ Automatically mount all available VAAPI devices? [Y/n]: " VAAPI_ALL if [[ "$VAAPI_ALL" =~ ^[Yy]$|^$ ]]; then - # Mount all devices automatically - if [[ -e /dev/dri/renderD128 ]]; then - echo "lxc.cgroup2.devices.allow: c 226:128 rwm" >>"$LXC_CONFIG" - echo "lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file" >>"$LXC_CONFIG" - fi - if [[ -e /dev/dri/card0 ]]; then - echo "lxc.cgroup2.devices.allow: c 226:0 rwm" >>"$LXC_CONFIG" - echo "lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file" >>"$LXC_CONFIG" - fi - if [[ -e /dev/fb0 ]]; then - echo "lxc.cgroup2.devices.allow: c 29:0 rwm" >>"$LXC_CONFIG" - echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >>"$LXC_CONFIG" - fi - if [[ -d /dev/dri ]]; then - echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG" - fi - else - # Manual selection per device - if [[ -e /dev/dri/renderD128 ]]; then - read -rp "➤ Mount /dev/dri/renderD128 (GPU rendering)? [y/N]: " MOUNT_D128 - if [[ "$MOUNT_D128" =~ ^[Yy]$ ]]; then + if [ "$CT_TYPE" == "0" ]; then + # PRV Container → alles zulässig + [[ -e /dev/dri/renderD128 ]] && { echo "lxc.cgroup2.devices.allow: c 226:128 rwm" >>"$LXC_CONFIG" echo "lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file" >>"$LXC_CONFIG" - fi - fi - - if [[ -e /dev/dri/card0 ]]; then - read -rp "➤ Mount /dev/dri/card0 (GPU hardware interface)? [y/N]: " MOUNT_CARD0 - if [[ "$MOUNT_CARD0" =~ ^[Yy]$ ]]; then + } + [[ -e /dev/dri/card0 ]] && { echo "lxc.cgroup2.devices.allow: c 226:0 rwm" >>"$LXC_CONFIG" echo "lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file" >>"$LXC_CONFIG" - fi - fi - - if [[ -e /dev/fb0 ]]; then - read -rp "➤ Mount /dev/fb0 (Framebuffer, GUI)? [y/N]: " MOUNT_FB0 - if [[ "$MOUNT_FB0" =~ ^[Yy]$ ]]; then + } + [[ -e /dev/fb0 ]] && { echo "lxc.cgroup2.devices.allow: c 29:0 rwm" >>"$LXC_CONFIG" echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >>"$LXC_CONFIG" - fi - fi - - if [[ -d /dev/dri ]]; then - echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG" + } + [[ -d /dev/dri ]] && { + echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG" + } + else + # UNPRV Container → nur devX für UI + [[ -e /dev/dri/card0 ]] && echo "dev0: /dev/dri/card0,gid=44" >>"$LXC_CONFIG" + [[ -e /dev/dri/card1 ]] && echo "dev0: /dev/dri/card1,gid=44" >>"$LXC_CONFIG" + [[ -e /dev/dri/renderD128 ]] && echo "dev1: /dev/dri/renderD128,gid=104" >>"$LXC_CONFIG" fi fi + fi if [ "$CT_TYPE" == "1" ] && [ "$is_vaapi_app" == "true" ]; then if [[ -e /dev/dri/card0 ]]; then From d2d2662ca3d0413d283a151927c319e43b4444b2 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 9 Jul 2025 15:31:54 +0200 Subject: [PATCH 253/463] Update debian.sh --- ct/debian.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian.sh b/ct/debian.sh index c525e5e2..87fa7f65 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -12,7 +12,7 @@ var_ram="${var_ram:-512}" var_disk="${var_disk:-2}" var_os="${var_os:-debian}" var_version="${var_version:-12}" -var_unprivileged="${var_unprivileged:-1}" +var_unprivileged="${var_unprivileged:-0}" var_fuse="${var_fuse:-no}" var_tun="${var_tun:-no}" From e1f88da0b70bbef2aaff966d6d48df379f3cf3c9 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Thu, 10 Jul 2025 01:41:44 +0000 Subject: [PATCH 254/463] Update versions.json (#695) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 190 ++++++++++++----------------- 1 file changed, 80 insertions(+), 110 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index eba1ee34..6a2867b3 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,24 +1,89 @@ [ + { + "name": "steveiliop56/tinyauth", + "version": "v3.6.0", + "date": "2025-07-09T23:15:25Z" + }, + { + "name": "pocket-id/pocket-id", + "version": "v1.6.2", + "date": "2025-07-09T22:14:10Z" + }, + { + "name": "NginxProxyManager/nginx-proxy-manager", + "version": "v2.12.6", + "date": "2025-07-09T21:52:15Z" + }, + { + "name": "apache/tika", + "version": "3.2.1", + "date": "2025-07-09T20:47:29Z" + }, + { + "name": "sabnzbd/sabnzbd", + "version": "4.5.2", + "date": "2025-07-09T19:08:28Z" + }, + { + "name": "raydak-labs/configarr", + "version": "v1.13.6", + "date": "2025-07-09T17:23:01Z" + }, + { + "name": "msgbyte/tianji", + "version": "v1.23.3", + "date": "2025-07-09T16:39:30Z" + }, + { + "name": "hargata/lubelog", + "version": "v1.4.9", + "date": "2025-07-09T16:27:46Z" + }, + { + "name": "duplicati/duplicati", + "version": "v2.1.0.123-2.1.0.123_canary_2025-07-09", + "date": "2025-07-09T16:08:36Z" + }, + { + "name": "keycloak/keycloak", + "version": "26.3.1", + "date": "2025-07-09T15:41:43Z" + }, + { + "name": "nicolargo/glances", + "version": "v4.3.3", + "date": "2025-07-09T15:35:44Z" + }, + { + "name": "rclone/rclone", + "version": "v1.70.3", + "date": "2025-07-09T15:06:31Z" + }, + { + "name": "home-assistant/operating-system", + "version": "16.0", + "date": "2025-07-09T13:28:43Z" + }, + { + "name": "element-hq/synapse", + "version": "v1.133.0", + "date": "2025-07-01T15:13:42Z" + }, + { + "name": "AdguardTeam/AdGuardHome", + "version": "v0.107.63", + "date": "2025-06-26T14:34:19Z" + }, { "name": "crowdsecurity/crowdsec", "version": "v1.6.9", "date": "2025-06-17T11:54:50Z" }, - { - "name": "element-hq/synapse", - "version": "v1.134.0rc1", - "date": "2025-07-09T11:33:33Z" - }, { "name": "n8n-io/n8n", "version": "n8n@1.102.0", "date": "2025-07-07T15:32:29Z" }, - { - "name": "rclone/rclone", - "version": "v1.70.3", - "date": "2025-07-09T10:02:39Z" - }, { "name": "fuma-nama/fumadocs", "version": "fumadocs-ui@15.6.3", @@ -44,21 +109,11 @@ "version": "4.9.1.2", "date": "2025-06-26T22:08:00Z" }, - { - "name": "NginxProxyManager/nginx-proxy-manager", - "version": "v2.14.5", - "date": "2025-07-09T04:41:02Z" - }, { "name": "henrygd/beszel", "version": "v0.11.1", "date": "2025-04-29T01:14:35Z" }, - { - "name": "steveiliop56/tinyauth", - "version": "v3.4.1", - "date": "2025-06-11T07:53:44Z" - }, { "name": "Prowlarr/Prowlarr", "version": "v1.37.0.5076", @@ -89,11 +144,6 @@ "version": "v1.0.2", "date": "2025-07-08T19:14:31Z" }, - { - "name": "keycloak/keycloak", - "version": "26.3.0", - "date": "2025-07-02T12:26:44Z" - }, { "name": "TwiN/gatus", "version": "v5.20.0", @@ -109,6 +159,11 @@ "version": "v1.6.2", "date": "2025-07-08T13:52:33Z" }, + { + "name": "wazuh/wazuh", + "version": "coverity-w28-4.13.0", + "date": "2025-07-08T11:25:24Z" + }, { "name": "mattermost/mattermost", "version": "preview-v0.1", @@ -134,16 +189,6 @@ "version": "r8.0.12-rc0", "date": "2025-07-07T23:35:35Z" }, - { - "name": "duplicati/duplicati", - "version": "v2.1.0.122-2.1.0.122_canary_2025-07-07", - "date": "2025-07-07T17:54:52Z" - }, - { - "name": "msgbyte/tianji", - "version": "v1.23.2", - "date": "2025-07-07T16:51:43Z" - }, { "name": "TandoorRecipes/recipes", "version": "1.5.35", @@ -214,11 +259,6 @@ "version": "v1.0.0-beta14", "date": "2025-07-06T21:07:07Z" }, - { - "name": "pocket-id/pocket-id", - "version": "v1.6.1", - "date": "2025-07-06T20:59:34Z" - }, { "name": "Luligu/matterbridge", "version": "3.1.2", @@ -264,11 +304,6 @@ "version": "v6.12.7", "date": "2025-06-18T03:44:24Z" }, - { - "name": "nicolargo/glances", - "version": "v4.3.2", - "date": "2025-07-05T16:00:15Z" - }, { "name": "runtipi/runtipi", "version": "v4.3.0", @@ -319,11 +354,6 @@ "version": "v0.85.0", "date": "2025-07-04T00:06:47Z" }, - { - "name": "home-assistant/operating-system", - "version": "15.2", - "date": "2025-04-14T15:37:12Z" - }, { "name": "cloudflare/cloudflared", "version": "2025.7.0", @@ -354,21 +384,11 @@ "version": "v1.12.2-rc.0", "date": "2025-07-03T00:31:22Z" }, - { - "name": "hargata/lubelog", - "version": "v1.4.8", - "date": "2025-07-02T21:15:13Z" - }, { "name": "Koenkk/zigbee2mqtt", "version": "2.5.1", "date": "2025-07-02T19:38:06Z" }, - { - "name": "wazuh/wazuh", - "version": "coverity-w27-4.13.0", - "date": "2025-07-01T03:17:32Z" - }, { "name": "glpi-project/glpi", "version": "10.0.18", @@ -443,55 +463,5 @@ "name": "jupyter/notebook", "version": "v7.4.4", "date": "2025-06-30T13:04:22Z" - }, - { - "name": "PrivateBin/PrivateBin", - "version": "1.7.8", - "date": "2025-06-30T09:00:54Z" - }, - { - "name": "typesense/typesense", - "version": "v29.0", - "date": "2025-06-30T03:52:33Z" - }, - { - "name": "dgtlmoon/changedetection.io", - "version": "0.50.5", - "date": "2025-06-29T08:54:47Z" - }, - { - "name": "plexguide/Huntarr.io", - "version": "8.1.11", - "date": "2025-06-28T03:42:46Z" - }, - { - "name": "tobychui/zoraxy", - "version": "v3.2.4", - "date": "2025-06-28T02:47:31Z" - }, - { - "name": "goauthentik/authentik", - "version": "version/2025.6.3", - "date": "2025-06-27T14:01:06Z" - }, - { - "name": "sabnzbd/sabnzbd", - "version": "4.5.1", - "date": "2025-04-11T09:57:47Z" - }, - { - "name": "FlowiseAI/Flowise", - "version": "flowise@3.0.3", - "date": "2025-06-27T09:53:57Z" - }, - { - "name": "netbox-community/netbox", - "version": "v4.3.3", - "date": "2025-06-26T18:42:56Z" - }, - { - "name": "apache/tika", - "version": "3.2.1-rc2", - "date": "2025-06-26T17:10:25Z" } ] From f3adda0d5e90740757b969f55b06de6fef9c27b1 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 08:49:11 +0200 Subject: [PATCH 255/463] Update create_lxc.sh --- misc/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 2b48093c..02fad359 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -274,7 +274,7 @@ TEMPLATE="${TEMPLATES[-1]}" TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || echo "/var/lib/vz/template/cache/$TEMPLATE")" # Check if template exists and is valid -if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE" || ! zstdcat "$TEMPLATE_PATH" | tar -tf - >/dev/null 2>&1; then +if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE" || ! (zstdcat "$TEMPLATE_PATH" | tar -tf - >/dev/null 2>&1); then msg_warn "Template $TEMPLATE not found or appears to be corrupted. Re-downloading." [[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH" From 24a6eb0eb1a976c297acd944f8f5988aca562683 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 08:53:05 +0200 Subject: [PATCH 256/463] Update create_lxc.sh --- misc/create_lxc.sh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 02fad359..62fa9848 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -273,24 +273,28 @@ fi TEMPLATE="${TEMPLATES[-1]}" TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || echo "/var/lib/vz/template/cache/$TEMPLATE")" -# Check if template exists and is valid -if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE" || ! (zstdcat "$TEMPLATE_PATH" | tar -tf - >/dev/null 2>&1); then - msg_warn "Template $TEMPLATE not found or appears to be corrupted. Re-downloading." +TEMPLATE_VALID=1 +if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then + TEMPLATE_VALID=0 +elif [ ! -s "$TEMPLATE_PATH" ]; then + TEMPLATE_VALID=0 +elif ! tar --use-compress-program=zstdcat -tf "$TEMPLATE_PATH" >/dev/null 2>&1; then + TEMPLATE_VALID=0 +fi +if [ "$TEMPLATE_VALID" -eq 0 ]; then + msg_warn "Template $TEMPLATE not found or appears to be corrupted. Re-downloading." [[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH" for attempt in {1..3}; do msg_info "Attempt $attempt: Downloading LXC template..." - if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then msg_ok "Template download successful." break fi - if [ $attempt -eq 3 ]; then - msg_error "Failed after 3 attempts. Please check your Proxmox host’s internet access or manually run:\n pveam download $TEMPLATE_STORAGE $TEMPLATE" + msg_error "Failed after 3 attempts. Please check network access or manually run:\n pveam download $TEMPLATE_STORAGE $TEMPLATE" exit 208 fi - sleep $((attempt * 5)) done fi From 8a28fa2d251b8672f407b11c2340a10d536a685b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 09:01:03 +0200 Subject: [PATCH 257/463] Update create_lxc.sh --- misc/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 62fa9848..0e55a0ed 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -283,7 +283,7 @@ elif ! tar --use-compress-program=zstdcat -tf "$TEMPLATE_PATH" >/dev/null 2>&1; fi if [ "$TEMPLATE_VALID" -eq 0 ]; then - msg_warn "Template $TEMPLATE not found or appears to be corrupted. Re-downloading." + msg_warn "Template $TEMPLATE not found or appears to be corrupted. Re-downloading. 11" [[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH" for attempt in {1..3}; do msg_info "Attempt $attempt: Downloading LXC template..." From bdf8f86c006a7042c7b708d43c9782ef460941df Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 09:06:00 +0200 Subject: [PATCH 258/463] Update create_lxc.sh --- misc/create_lxc.sh | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 0e55a0ed..68063850 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -271,33 +271,31 @@ if [ ${#TEMPLATES[@]} -eq 0 ]; then fi TEMPLATE="${TEMPLATES[-1]}" -TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || echo "/var/lib/vz/template/cache/$TEMPLATE")" - -TEMPLATE_VALID=1 -if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then - TEMPLATE_VALID=0 -elif [ ! -s "$TEMPLATE_PATH" ]; then - TEMPLATE_VALID=0 -elif ! tar --use-compress-program=zstdcat -tf "$TEMPLATE_PATH" >/dev/null 2>&1; then - TEMPLATE_VALID=0 -fi - -if [ "$TEMPLATE_VALID" -eq 0 ]; then - msg_warn "Template $TEMPLATE not found or appears to be corrupted. Re-downloading. 11" +TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE)" +# Without NAS/Mount: TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE" +# Check if template exists, if corrupt remove and redownload +if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE" || ! zstdcat "$TEMPLATE_PATH" | tar -tf - >/dev/null 2>&1; then + msg_warn "Template $TEMPLATE not found in storage or seems to be corrupted. Redownloading." [[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH" + + # Download with 3 attempts for attempt in {1..3}; do msg_info "Attempt $attempt: Downloading LXC template..." - if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then + + if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null; then msg_ok "Template download successful." break fi + if [ $attempt -eq 3 ]; then - msg_error "Failed after 3 attempts. Please check network access or manually run:\n pveam download $TEMPLATE_STORAGE $TEMPLATE" + msg_error "Three failed attempts. Aborting." exit 208 fi + sleep $((attempt * 5)) done fi +msg_ok "LXC Template is ready to use." msg_ok "LXC Template '$TEMPLATE' is ready to use." From ae97b0d22eb0614ea24b2829c2ca20dd7adaa9ac Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 09:10:11 +0200 Subject: [PATCH 259/463] Update create_lxc.sh --- misc/create_lxc.sh | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 68063850..6909f957 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -271,31 +271,42 @@ if [ ${#TEMPLATES[@]} -eq 0 ]; then fi TEMPLATE="${TEMPLATES[-1]}" -TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE)" -# Without NAS/Mount: TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE" -# Check if template exists, if corrupt remove and redownload -if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE" || ! zstdcat "$TEMPLATE_PATH" | tar -tf - >/dev/null 2>&1; then - msg_warn "Template $TEMPLATE not found in storage or seems to be corrupted. Redownloading." +TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || echo "/var/lib/vz/template/cache/$TEMPLATE")" + +TEMPLATE_VALID=1 +if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then + TEMPLATE_VALID=0 +elif [ ! -s "$TEMPLATE_PATH" ]; then + TEMPLATE_VALID=0 +elif ! tar --use-compress-program=zstdcat -tf "$TEMPLATE_PATH" >/dev/null 2>&1; then + TEMPLATE_VALID=0 +fi + +if [ "$TEMPLATE_VALID" -eq 0 ]; then + msg_warn "Template $TEMPLATE not found or appears to be corrupted. Re-downloading." [[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH" - # Download with 3 attempts for attempt in {1..3}; do msg_info "Attempt $attempt: Downloading LXC template..." - - if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null; then + if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then msg_ok "Template download successful." - break + + # 🔁 Prüfe Template sofort nochmal nach Download (Workaround für zstdcat/tar Stop) + if tar --use-compress-program=zstdcat -tf "$TEMPLATE_PATH" >/dev/null 2>&1; then + msg_ok "Template verified successfully after download." + break + else + msg_warn "Template check failed after download. Retrying..." + fi fi if [ $attempt -eq 3 ]; then - msg_error "Three failed attempts. Aborting." + msg_error "Failed after 3 attempts. Please check network access or manually run:\n pveam download $TEMPLATE_STORAGE $TEMPLATE" exit 208 fi - sleep $((attempt * 5)) done fi -msg_ok "LXC Template is ready to use." msg_ok "LXC Template '$TEMPLATE' is ready to use." From 6cb0a049d30dafabf937d01d1bce84269952073f Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 09:14:52 +0200 Subject: [PATCH 260/463] Update create_lxc.sh --- misc/create_lxc.sh | 65 +++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 6909f957..64825855 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -269,46 +269,45 @@ if [ ${#TEMPLATES[@]} -eq 0 ]; then msg_error "No matching LXC template found for '${TEMPLATE_SEARCH}'. Make sure your host can reach the Proxmox template repository." exit 207 fi +ensure_template_ready -TEMPLATE="${TEMPLATES[-1]}" -TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || echo "/var/lib/vz/template/cache/$TEMPLATE")" +ensure_template_ready() { + local template_path + template_path="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || echo "/var/lib/vz/template/cache/$TEMPLATE")" -TEMPLATE_VALID=1 -if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then - TEMPLATE_VALID=0 -elif [ ! -s "$TEMPLATE_PATH" ]; then - TEMPLATE_VALID=0 -elif ! tar --use-compress-program=zstdcat -tf "$TEMPLATE_PATH" >/dev/null 2>&1; then - TEMPLATE_VALID=0 -fi + if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then + msg_warn "Template $TEMPLATE not listed in storage '$TEMPLATE_STORAGE'." + template_invalid=1 + elif [ ! -s "$template_path" ]; then + msg_warn "Template file $template_path is empty or missing." + template_invalid=1 + elif ! tar --use-compress-program=zstdcat -tf "$template_path" >/dev/null 2>&1; then + msg_warn "Template $template_path failed archive integrity check." + template_invalid=1 + else + template_invalid=0 + fi -if [ "$TEMPLATE_VALID" -eq 0 ]; then - msg_warn "Template $TEMPLATE not found or appears to be corrupted. Re-downloading." - [[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH" + if [ "$template_invalid" -eq 1 ]; then + [[ -f "$template_path" ]] && rm -f "$template_path" - for attempt in {1..3}; do - msg_info "Attempt $attempt: Downloading LXC template..." - if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then - msg_ok "Template download successful." - - # 🔁 Prüfe Template sofort nochmal nach Download (Workaround für zstdcat/tar Stop) - if tar --use-compress-program=zstdcat -tf "$TEMPLATE_PATH" >/dev/null 2>&1; then - msg_ok "Template verified successfully after download." - break - else - msg_warn "Template check failed after download. Retrying..." + for attempt in {1..3}; do + msg_info "Attempt $attempt: Downloading LXC template..." + if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then + msg_ok "Template download successful." + # 🔁 Nach erfolgreichem Download rekursiv erneut prüfen + ensure_template_ready + return fi - fi + sleep $((attempt * 5)) + done - if [ $attempt -eq 3 ]; then - msg_error "Failed after 3 attempts. Please check network access or manually run:\n pveam download $TEMPLATE_STORAGE $TEMPLATE" - exit 208 - fi - sleep $((attempt * 5)) - done -fi + msg_error "Template download failed after 3 attempts. Check internet or run:\n pveam download $TEMPLATE_STORAGE $TEMPLATE" + exit 208 + fi -msg_ok "LXC Template '$TEMPLATE' is ready to use." + msg_ok "LXC Template '$TEMPLATE' is ready to use." +} msg_info "Creating LXC Container" # Check and fix subuid/subgid From dcfe74d7a3346133ea5aee56eca7a5581f3edf08 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 09:17:23 +0200 Subject: [PATCH 261/463] Update create_lxc.sh --- misc/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 64825855..3f5ce290 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -271,7 +271,7 @@ if [ ${#TEMPLATES[@]} -eq 0 ]; then fi ensure_template_ready -ensure_template_ready() { +function ensure_template_ready() { local template_path template_path="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || echo "/var/lib/vz/template/cache/$TEMPLATE")" From 6ccb62d19ed77dac4bfd7ceff2ff9860f4ec616a Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 09:20:34 +0200 Subject: [PATCH 262/463] Update create_lxc.sh --- misc/create_lxc.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 3f5ce290..2651c5bb 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -262,6 +262,7 @@ else fi # Get LXC template string +# TEMPLATE_SEARCH und TEMPLATES TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION:-}" mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) @@ -269,7 +270,8 @@ if [ ${#TEMPLATES[@]} -eq 0 ]; then msg_error "No matching LXC template found for '${TEMPLATE_SEARCH}'. Make sure your host can reach the Proxmox template repository." exit 207 fi -ensure_template_ready + +TEMPLATE="${TEMPLATES[-1]}" function ensure_template_ready() { local template_path @@ -295,7 +297,6 @@ function ensure_template_ready() { msg_info "Attempt $attempt: Downloading LXC template..." if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then msg_ok "Template download successful." - # 🔁 Nach erfolgreichem Download rekursiv erneut prüfen ensure_template_ready return fi @@ -309,6 +310,8 @@ function ensure_template_ready() { msg_ok "LXC Template '$TEMPLATE' is ready to use." } +ensure_template_ready + msg_info "Creating LXC Container" # Check and fix subuid/subgid grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >>/etc/subuid From 37748f3f47a31152eceed554e7b10f6da61f11c0 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 09:23:35 +0200 Subject: [PATCH 263/463] Update create_lxc.sh --- misc/create_lxc.sh | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 2651c5bb..6a5a4477 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -293,18 +293,13 @@ function ensure_template_ready() { if [ "$template_invalid" -eq 1 ]; then [[ -f "$template_path" ]] && rm -f "$template_path" - for attempt in {1..3}; do - msg_info "Attempt $attempt: Downloading LXC template..." - if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then - msg_ok "Template download successful." - ensure_template_ready - return - fi - sleep $((attempt * 5)) - done - - msg_error "Template download failed after 3 attempts. Check internet or run:\n pveam download $TEMPLATE_STORAGE $TEMPLATE" - exit 208 + msg_info "Downloading LXC template..." + if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then + msg_ok "Template download successful." + else + msg_error "Template download failed. Check internet or run manually:\n pveam download $TEMPLATE_STORAGE $TEMPLATE" + exit 208 + fi fi msg_ok "LXC Template '$TEMPLATE' is ready to use." From 9f6bce842748b8bea9fe39be24ae2c0f37e7f04e Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 09:46:15 +0200 Subject: [PATCH 264/463] Update create_lxc.sh --- misc/create_lxc.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 6a5a4477..bc77acbe 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -283,9 +283,6 @@ function ensure_template_ready() { elif [ ! -s "$template_path" ]; then msg_warn "Template file $template_path is empty or missing." template_invalid=1 - elif ! tar --use-compress-program=zstdcat -tf "$template_path" >/dev/null 2>&1; then - msg_warn "Template $template_path failed archive integrity check." - template_invalid=1 else template_invalid=0 fi From 7dca60f0f5e35420ca4030f4e7c2b22c0d0f88ea Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 09:53:23 +0200 Subject: [PATCH 265/463] Update create_lxc.sh --- misc/create_lxc.sh | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index bc77acbe..f7946e6a 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -274,8 +274,11 @@ fi TEMPLATE="${TEMPLATES[-1]}" function ensure_template_ready() { + echo "[DEBUG] ensure_template_ready() gestartet" + local template_path template_path="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || echo "/var/lib/vz/template/cache/$TEMPLATE")" + echo "[DEBUG] template_path=$template_path" if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then msg_warn "Template $TEMPLATE not listed in storage '$TEMPLATE_STORAGE'." @@ -287,11 +290,22 @@ function ensure_template_ready() { template_invalid=0 fi + echo "[DEBUG] template_invalid=$template_invalid" + if [ "$template_invalid" -eq 1 ]; then - [[ -f "$template_path" ]] && rm -f "$template_path" + [[ -f "$template_path" ]] && { + echo "[DEBUG] removing template_path $template_path" + rm -f "$template_path" + } msg_info "Downloading LXC template..." - if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then + echo "[DEBUG] calling pveam download" + sleep 0.2 + timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1 + dl_result=$? + echo "[DEBUG] pveam download exit=$dl_result" + + if [ $dl_result -eq 0 ]; then msg_ok "Template download successful." else msg_error "Template download failed. Check internet or run manually:\n pveam download $TEMPLATE_STORAGE $TEMPLATE" @@ -299,6 +313,7 @@ function ensure_template_ready() { fi fi + echo "[DEBUG] ensure_template_ready() abgeschlossen" msg_ok "LXC Template '$TEMPLATE' is ready to use." } From 34814cd8be64c4a115d13318c50d922c127a86d7 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 09:56:17 +0200 Subject: [PATCH 266/463] Update create_lxc.sh --- misc/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index f7946e6a..851efe5d 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -306,7 +306,7 @@ function ensure_template_ready() { echo "[DEBUG] pveam download exit=$dl_result" if [ $dl_result -eq 0 ]; then - msg_ok "Template download successful." + echo "[DEBUG] msg_ok skipped (would say: Template download successful)" else msg_error "Template download failed. Check internet or run manually:\n pveam download $TEMPLATE_STORAGE $TEMPLATE" exit 208 From ae6a6bff81f9cfa08ce246b9976ba7ff963af6dd Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 10:02:17 +0200 Subject: [PATCH 267/463] Update core.func --- misc/core.func | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/misc/core.func b/misc/core.func index a8774fc2..b4293ca6 100644 --- a/misc/core.func +++ b/misc/core.func @@ -327,6 +327,10 @@ fatal() { kill -INT $$ } +# ------------------------------------------------------------------------------ +# Spinner- und Messaging-Framework (TTY-sicher, CI-kompatibel) +# ------------------------------------------------------------------------------ + spinner() { local chars=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏) local i=0 @@ -337,11 +341,6 @@ spinner() { done } -clear_line() { - tput cr 2>/dev/null || echo -en "\r" - tput el 2>/dev/null || echo -en "\033[K" -} - stop_spinner() { local pid="${SPINNER_PID:-}" [[ -z "$pid" && -f /tmp/.spinner.pid ]] && pid=$(&2 + printf "\r\e[2K%s %b\n" "$HOURGLASS" "${YW}${msg}${CL}" >&2 return fi - color_spinner - spinner & - SPINNER_PID=$! - echo "$SPINNER_PID" >/tmp/.spinner.pid - disown "$SPINNER_PID" 2>/dev/null || true + # Spinner nur starten, wenn ein echtes TTY und keine SIGTTOU-Gefahr + if [[ -t 1 && ! "$(ps -o stat= -p $$)" =~ T && -z "$NO_SPINNER" ]]; then + color_spinner + spinner & + SPINNER_PID=$! + echo "$SPINNER_PID" >/tmp/.spinner.pid + disown "$SPINNER_PID" 2>/dev/null || true + else + # Fallback: reiner Text + printf "\r\e[2K⏳ %b\n" "${YW}${msg}${CL}" >&2 + fi } msg_ok() { @@ -415,6 +421,11 @@ msg_custom() { echo -e "${BFR:-} ${symbol} ${color}${msg}${CL:-\e[0m}" } +clear_line() { + tput cr 2>/dev/null || echo -en "\r" + tput el 2>/dev/null || echo -en "\033[K" +} + # msg_ok() { # local msg="$1" # [[ -z "$msg" ]] && return From 9e8af1530840faa0f0abf72558df199cc8fca65b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 10:04:46 +0200 Subject: [PATCH 268/463] Update core.func --- misc/core.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/core.func b/misc/core.func index b4293ca6..d08a9de5 100644 --- a/misc/core.func +++ b/misc/core.func @@ -379,7 +379,7 @@ msg_info() { fi # Spinner nur starten, wenn ein echtes TTY und keine SIGTTOU-Gefahr - if [[ -t 1 && ! "$(ps -o stat= -p $$)" =~ T && -z "$NO_SPINNER" ]]; then + if [[ -t 1 && ! "$(ps -o stat= -p $$)" =~ T && -z "${NO_SPINNER:-}" ]] color_spinner spinner & SPINNER_PID=$! From bbb65624b7efe1dd816b29dccc56e5998602324e Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 10:07:06 +0200 Subject: [PATCH 269/463] Update core.func --- misc/core.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/core.func b/misc/core.func index d08a9de5..0f6f05d6 100644 --- a/misc/core.func +++ b/misc/core.func @@ -379,7 +379,7 @@ msg_info() { fi # Spinner nur starten, wenn ein echtes TTY und keine SIGTTOU-Gefahr - if [[ -t 1 && ! "$(ps -o stat= -p $$)" =~ T && -z "${NO_SPINNER:-}" ]] + if [[ -t 1 && ! "$(ps -o stat= -p $$)" =~ T && -z "${NO_SPINNER:-}" ]]; then color_spinner spinner & SPINNER_PID=$! From dd73f644f4559c4ea49c699cf4e3a70ea5394324 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 10:09:13 +0200 Subject: [PATCH 270/463] Update create_lxc.sh --- misc/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 851efe5d..33948511 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -314,7 +314,7 @@ function ensure_template_ready() { fi echo "[DEBUG] ensure_template_ready() abgeschlossen" - msg_ok "LXC Template '$TEMPLATE' is ready to use." + #msg_ok "LXC Template '$TEMPLATE' is ready to use." } ensure_template_ready From d2133a883ed0c603d4bb00adb652fbd89d1f6cf3 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 10:14:00 +0200 Subject: [PATCH 271/463] Update create_lxc.sh --- misc/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index 33948511..daa6b71c 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -301,7 +301,7 @@ function ensure_template_ready() { msg_info "Downloading LXC template..." echo "[DEBUG] calling pveam download" sleep 0.2 - timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1 + pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1 dl_result=$? echo "[DEBUG] pveam download exit=$dl_result" From 1b2e270b08feb6e58960397f4145a9c3dbae176d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 10:22:32 +0200 Subject: [PATCH 272/463] Update create_lxc.sh --- misc/create_lxc.sh | 66 +++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 42 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index daa6b71c..d74ee9fa 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -262,7 +262,6 @@ else fi # Get LXC template string -# TEMPLATE_SEARCH und TEMPLATES TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION:-}" mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) @@ -272,52 +271,35 @@ if [ ${#TEMPLATES[@]} -eq 0 ]; then fi TEMPLATE="${TEMPLATES[-1]}" +TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || echo "/var/lib/vz/template/cache/$TEMPLATE")" -function ensure_template_ready() { - echo "[DEBUG] ensure_template_ready() gestartet" +TEMPLATE_VALID=1 +if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then + TEMPLATE_VALID=0 +elif [ ! -s "$TEMPLATE_PATH" ]; then + TEMPLATE_VALID=0 +elif ! tar --use-compress-program=zstdcat -tf "$TEMPLATE_PATH" >/dev/null 2>&1; then + TEMPLATE_VALID=0 +fi - local template_path - template_path="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || echo "/var/lib/vz/template/cache/$TEMPLATE")" - echo "[DEBUG] template_path=$template_path" - - if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then - msg_warn "Template $TEMPLATE not listed in storage '$TEMPLATE_STORAGE'." - template_invalid=1 - elif [ ! -s "$template_path" ]; then - msg_warn "Template file $template_path is empty or missing." - template_invalid=1 - else - template_invalid=0 - fi - - echo "[DEBUG] template_invalid=$template_invalid" - - if [ "$template_invalid" -eq 1 ]; then - [[ -f "$template_path" ]] && { - echo "[DEBUG] removing template_path $template_path" - rm -f "$template_path" - } - - msg_info "Downloading LXC template..." - echo "[DEBUG] calling pveam download" - sleep 0.2 - pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1 - dl_result=$? - echo "[DEBUG] pveam download exit=$dl_result" - - if [ $dl_result -eq 0 ]; then - echo "[DEBUG] msg_ok skipped (would say: Template download successful)" - else - msg_error "Template download failed. Check internet or run manually:\n pveam download $TEMPLATE_STORAGE $TEMPLATE" +if [ "$TEMPLATE_VALID" -eq 0 ]; then + msg_warn "Template $TEMPLATE not found or appears to be corrupted. Re-downloading." + [[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH" + for attempt in {1..3}; do + msg_info "Attempt $attempt: Downloading LXC template..." + if pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then + msg_ok "Template download successful." + break + fi + if [ $attempt -eq 3 ]; then + msg_error "Failed after 3 attempts. Please check network access or manually run:\n pveam download $TEMPLATE_STORAGE $TEMPLATE" exit 208 fi - fi + sleep $((attempt * 5)) + done +fi - echo "[DEBUG] ensure_template_ready() abgeschlossen" - #msg_ok "LXC Template '$TEMPLATE' is ready to use." -} - -ensure_template_ready +msg_ok "LXC Template '$TEMPLATE' is ready to use." msg_info "Creating LXC Container" # Check and fix subuid/subgid From 6c602da50f6f8e329e2d7896289c0a0419f0a6e8 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 10:22:38 +0200 Subject: [PATCH 273/463] Update core.func --- misc/core.func | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/misc/core.func b/misc/core.func index 0f6f05d6..a8774fc2 100644 --- a/misc/core.func +++ b/misc/core.func @@ -327,10 +327,6 @@ fatal() { kill -INT $$ } -# ------------------------------------------------------------------------------ -# Spinner- und Messaging-Framework (TTY-sicher, CI-kompatibel) -# ------------------------------------------------------------------------------ - spinner() { local chars=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏) local i=0 @@ -341,6 +337,11 @@ spinner() { done } +clear_line() { + tput cr 2>/dev/null || echo -en "\r" + tput el 2>/dev/null || echo -en "\033[K" +} + stop_spinner() { local pid="${SPINNER_PID:-}" [[ -z "$pid" && -f /tmp/.spinner.pid ]] && pid=$(&2 + printf "\r\e[2K%s %b" "$HOURGLASS" "${YW}${msg}${CL}" >&2 return fi - # Spinner nur starten, wenn ein echtes TTY und keine SIGTTOU-Gefahr - if [[ -t 1 && ! "$(ps -o stat= -p $$)" =~ T && -z "${NO_SPINNER:-}" ]]; then - color_spinner - spinner & - SPINNER_PID=$! - echo "$SPINNER_PID" >/tmp/.spinner.pid - disown "$SPINNER_PID" 2>/dev/null || true - else - # Fallback: reiner Text - printf "\r\e[2K⏳ %b\n" "${YW}${msg}${CL}" >&2 - fi + color_spinner + spinner & + SPINNER_PID=$! + echo "$SPINNER_PID" >/tmp/.spinner.pid + disown "$SPINNER_PID" 2>/dev/null || true } msg_ok() { @@ -421,11 +415,6 @@ msg_custom() { echo -e "${BFR:-} ${symbol} ${color}${msg}${CL:-\e[0m}" } -clear_line() { - tput cr 2>/dev/null || echo -en "\r" - tput el 2>/dev/null || echo -en "\033[K" -} - # msg_ok() { # local msg="$1" # [[ -z "$msg" ]] && return From f9d60db88ebd5aee485aab08c4b3ff27f6a0d8c8 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 10:52:30 +0200 Subject: [PATCH 274/463] cleanup --- ct/ersatztv.sh | 56 --------- ct/openwebui.sh | 81 ------------- ct/stirling-pdf.sh | 62 ---------- ct/trilium.sh | 85 -------------- install/ersatztv-install.sh | 57 --------- install/openwebui-install.sh | 99 ---------------- install/stirling-pdf-install.sh | 201 -------------------------------- install/trilium-install.sh | 44 ------- 8 files changed, 685 deletions(-) delete mode 100644 ct/ersatztv.sh delete mode 100644 ct/openwebui.sh delete mode 100644 ct/stirling-pdf.sh delete mode 100644 ct/trilium.sh delete mode 100644 install/ersatztv-install.sh delete mode 100644 install/openwebui-install.sh delete mode 100644 install/stirling-pdf-install.sh delete mode 100644 install/trilium-install.sh diff --git a/ct/ersatztv.sh b/ct/ersatztv.sh deleted file mode 100644 index c1e477ac..00000000 --- a/ct/ersatztv.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2025 tteck -# Author: MickLesk (Canbiz) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://ersatztv.org/ - -APP="ErsatzTV" -var_tags="${var_tags:-iptv}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-1024}" -var_disk="${var_disk:-5}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -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/ErsatzTV ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - RELEASE=$(curl -fsSL https://api.github.com/repos/ErsatzTV/ErsatzTV/releases | grep -oP '"tag_name": "\K[^"]+' | head -n 1) - if [[ "${RELEASE}" != "$(cat ~/.ersatztv 2>/dev/null)" ]] || [[ ! -f ~/.ersatztv ]]; then - msg_info "Stopping ErsatzTV" - systemctl stop ersatzTV - msg_ok "Stopped ErsatzTV" - - FFMPEG_VERSION="latest" FFMPEG_TYPE="medium" setup_ffmpeg - fetch_and_deploy_gh_release "ersatztv" "ErsatzTV/ErsatzTV" "prebuild" "latest" "/opt/ErsatzTV" "*linux-x64.tar.gz" - - msg_info "Starting ErsatzTV" - systemctl start ersatzTV - msg_ok "Started ErsatzTV" - - msg_ok "Updated Successfully" - else - msg_ok "No update required. ${APP} is already at ${RELEASE}" - 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}http://${IP}:8409${CL}" diff --git a/ct/openwebui.sh b/ct/openwebui.sh deleted file mode 100644 index 86707daf..00000000 --- a/ct/openwebui.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2025 tteck -# Author: havardthom -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://openwebui.com/ - -APP="Open WebUI" -var_tags="${var_tags:-ai;interface}" -var_cpu="${var_cpu:-4}" -var_ram="${var_ram:-8192}" -var_disk="${var_disk:-25}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -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/open-webui ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - - if [ -x "/usr/bin/ollama" ]; then - msg_info "Updating Ollama" - OLLAMA_VERSION=$(ollama -v | awk '{print $NF}') - RELEASE=$(curl -s https://api.github.com/repos/ollama/ollama/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4)}') - if [ "$OLLAMA_VERSION" != "$RELEASE" ]; then - rm -rf /usr/lib/ollama - rm -rf /usr/bin/ollama - curl -fsSLO https://ollama.com/download/ollama-linux-amd64.tgz - tar -C /usr -xzf ollama-linux-amd64.tgz - rm -rf ollama-linux-amd64.tgz - msg_ok "Ollama updated to version $RELEASE" - else - msg_ok "Ollama is already up to date." - fi - fi - - msg_info "Updating ${APP} (Patience)" - cd /opt/open-webui - mkdir -p /opt/open-webui-backup - cp -rf /opt/open-webui/backend/data /opt/open-webui-backup - git add -A - $STD git stash - $STD git reset --hard - output=$(git pull --no-rebase) - if echo "$output" | grep -q "Already up to date."; then - msg_ok "$APP is already up to date." - exit - fi - systemctl stop open-webui.service - $STD npm install - export NODE_OPTIONS="--max-old-space-size=3584" - $STD npm run build - cd ./backend - $STD pip install -r requirements.txt -U - cp -rf /opt/open-webui-backup/* /opt/open-webui/backend - if git stash list | grep -q 'stash@{'; then - $STD git stash pop - fi - systemctl start open-webui.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}:8080${CL}" diff --git a/ct/stirling-pdf.sh b/ct/stirling-pdf.sh deleted file mode 100644 index 0c1ad5f1..00000000 --- a/ct/stirling-pdf.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2025 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://www.stirlingpdf.com/ - -APP="Stirling-PDF" -var_tags="${var_tags:-pdf-editor}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-2048}" -var_disk="${var_disk:-8}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -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/Stirling-PDF ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - msg_info "Updating ${APP}" - systemctl stop stirlingpdf - if [[ -n $(dpkg -l | grep -w ocrmypdf) ]] && [[ -z $(dpkg -l | grep -w qpdf) ]]; then - $STD apt-get remove -y ocrmypdf - $STD apt-get install -y qpdf - fi - RELEASE=$(curl -fsSL https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') - curl -fsSL "https://github.com/Stirling-Tools/Stirling-PDF/archive/refs/tags/v$RELEASE.tar.gz" -o $(basename "https://github.com/Stirling-Tools/Stirling-PDF/archive/refs/tags/v$RELEASE.tar.gz") - tar -xzf v$RELEASE.tar.gz - cd Stirling-PDF-$RELEASE - chmod +x ./gradlew - $STD ./gradlew build -x spotlessApply -x spotlessCheck -x test -x sonarqube - rm -rf /opt/Stirling-PDF/Stirling-PDF-*.jar - cp -r ./stirling-pdf/build/libs/*.jar /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar - cp -r scripts /opt/Stirling-PDF/ - cp -r pipeline /opt/Stirling-PDF/ - cp -r stirling-pdf/src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/ - cd ~ - rm -rf Stirling-PDF-$RELEASE v$RELEASE.tar.gz - ln -sf /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar /opt/Stirling-PDF/Stirling-PDF.jar - systemctl start stirlingpdf - msg_ok "Updated ${APP} to v$RELEASE" - 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}:8080${CL}" diff --git a/ct/trilium.sh b/ct/trilium.sh deleted file mode 100644 index 0a31428d..00000000 --- a/ct/trilium.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2025 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/TriliumNext/Trilium - -APP="Trilium" -var_tags="${var_tags:-notes}" -var_cpu="${var_cpu:-1}" -var_ram="${var_ram:-512}" -var_disk="${var_disk:-2}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -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/trilium ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - RELEASE=$(curl -fsSL https://api.github.com/repos/TriliumNext/Trilium/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') - if [[ "${RELEASE}" != "$(cat ~/.Trilium 2>/dev/null)" ]] || [[ ! -f ~/.Trilium ]]; then - - if [[ -d /opt/trilium/db ]]; then - DB_PATH="/opt/trilium/db" - DB_RESTORE_PATH="/opt/trilium/db" - elif [[ -d /opt/trilium/assets/db ]]; then - DB_PATH="/opt/trilium/assets/db" - DB_RESTORE_PATH="/opt/trilium/assets/db" - else - msg_error "Database not found in either /opt/trilium/db or /opt/trilium/assets/db" - exit 1 - fi - - msg_info "Stopping ${APP}" - systemctl stop trilium - sleep 1 - msg_ok "Stopped ${APP}" - - msg_info "Backing up Database" - mkdir -p /opt/trilium_backup - cp -r "${DB_PATH}" /opt/trilium_backup/ - rm -rf /opt/trilium - msg_ok "Backed up Database" - - fetch_and_deploy_gh_release "Trilium" "TriliumNext/Trilium" "prebuild" "latest" "/opt/trilium" "TriliumNotes-Server-*linux-x64.tar.xz" - - msg_info "Restoring Database" - mkdir -p "$(dirname "${DB_RESTORE_PATH}")" - cp -r /opt/trilium_backup/$(basename "${DB_PATH}") "${DB_RESTORE_PATH}" - msg_ok "Restored Database" - - msg_info "Cleaning up" - rm -rf /opt/trilium_backup - msg_ok "Cleaned" - - msg_info "Starting ${APP}" - systemctl start trilium - sleep 1 - msg_ok "Started ${APP}" - msg_ok "Updated Successfully" - else - msg_ok "No update required. ${APP} is already at ${RELEASE}" - 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}http://${IP}:8080${CL}" diff --git a/install/ersatztv-install.sh b/install/ersatztv-install.sh deleted file mode 100644 index eb0cc2f6..00000000 --- a/install/ersatztv-install.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 tteck -# Author: MickLesk (Canbiz) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://ersatztv.org/ - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -FFMPEG_VERSION="latest" FFMPEG_TYPE="medium" setup_ffmpeg - -msg_info "Setting Up Hardware Acceleration" -$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} -if [[ "$CTTYPE" == "0" ]]; then - chgrp video /dev/dri - chmod 755 /dev/dri - chmod 660 /dev/dri/* - $STD adduser $(id -u -n) video - $STD adduser $(id -u -n) render -fi -msg_ok "Set Up Hardware Acceleration" - -fetch_and_deploy_gh_release "ersatztv" "ErsatzTV/ErsatzTV" "prebuild" "latest" "/opt/ErsatzTV" "*linux-x64.tar.gz" - -msg_info "Creating Service" -cat </etc/systemd/system/ersatzTV.service -[Unit] -Description=ErsatzTV Service -After=multi-user.target - -[Service] -Type=simple -User=root -WorkingDirectory=/opt/ErsatzTV -ExecStart=/opt/ErsatzTV/ErsatzTV -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target -EOF -systemctl enable -q --now ersatzTV -msg_ok "Created Service" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" diff --git a/install/openwebui-install.sh b/install/openwebui-install.sh deleted file mode 100644 index af2b3611..00000000 --- a/install/openwebui-install.sh +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 tteck -# Author: tteck -# Co-Author: havardthom -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://openwebui.com/ - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apt-get install -y \ - git \ - ffmpeg -msg_ok "Installed Dependencies" - -msg_info "Setup Python3" -$STD apt-get install -y --no-install-recommends \ - python3 \ - python3-pip -msg_ok "Setup Python3" - -NODE_VERSION="22" setup_nodejs - -msg_info "Installing Open WebUI (Patience)" -$STD git clone https://github.com/open-webui/open-webui.git /opt/open-webui -cd /opt/open-webui/backend -$STD pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu -$STD pip3 install -r requirements.txt -U -cd /opt/open-webui -cp .env.example .env -cat </opt/open-webui/.env -ENV=prod -ENABLE_OLLAMA_API=false -OLLAMA_BASE_URL=http://0.0.0.0:11434 -EOF -$STD npm install -export NODE_OPTIONS="--max-old-space-size=3584" -$STD npm run build -msg_ok "Installed Open WebUI" - -read -r -p "${TAB3}Would you like to add Ollama? " prompt -if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then - msg_info "Installing Ollama" - curl -fsSLO https://ollama.com/download/ollama-linux-amd64.tgz - tar -C /usr -xzf ollama-linux-amd64.tgz - rm -rf ollama-linux-amd64.tgz - cat </etc/systemd/system/ollama.service -[Unit] -Description=Ollama Service -After=network-online.target - -[Service] -Type=exec -ExecStart=/usr/bin/ollama serve -Environment=HOME=$HOME -Environment=OLLAMA_HOST=0.0.0.0 -Restart=always -RestartSec=3 - -[Install] -WantedBy=multi-user.target -EOF - systemctl enable -q --now ollama - sed -i 's/ENABLE_OLLAMA_API=false/ENABLE_OLLAMA_API=true/g' /opt/open-webui/.env - msg_ok "Installed Ollama" -fi - -msg_info "Creating Service" -cat </etc/systemd/system/open-webui.service -[Unit] -Description=Open WebUI Service -After=network.target - -[Service] -Type=exec -WorkingDirectory=/opt/open-webui -EnvironmentFile=/opt/open-webui/.env -ExecStart=/opt/open-webui/backend/start.sh - -[Install] -WantedBy=multi-user.target -EOF -systemctl enable -q --now open-webui -msg_ok "Created Service" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh deleted file mode 100644 index 5a87a57a..00000000 --- a/install/stirling-pdf-install.sh +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://www.stirlingpdf.com/ - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies (Patience)" -$STD apt-get install -y \ - automake \ - autoconf \ - libtool \ - libleptonica-dev \ - pkg-config \ - zlib1g-dev \ - make \ - g++ \ - unpaper \ - fonts-urw-base35 \ - qpdf \ - poppler-utils -msg_ok "Installed Dependencies" - -PYTHON_VERSION="3.12" setup_uv -JAVA_VERSION="21" setup_java - -read -r -p "${TAB3}Do you want to Stirling-PDF with Login? (no/n = without Login) [Y/n] " response -response=${response,,} # Convert to lowercase -login_mode="false" -if [[ "$response" == "y" || "$response" == "yes" || -z "$response" ]]; then - USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF-with-login.jar" - mv /opt/Stirling-PDF/Stirling-PDF-with-login.jar /opt/Stirling-PDF/Stirling-PDF.jar - touch ~/.Stirling-PDF-login - login_mode="true" -else - USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF.jar" -fi - -msg_info "Installing LibreOffice Components" -$STD apt-get install -y \ - libreoffice-writer \ - libreoffice-calc \ - libreoffice-impress \ - libreoffice-core \ - libreoffice-common \ - libreoffice-base-core \ - libreoffice-script-provider-python \ - libreoffice-java-common \ - unoconv \ - pngquant \ - weasyprint -msg_ok "Installed LibreOffice Components" - -msg_info "Installing Python Dependencies" -mkdir -p /tmp/stirling-pdf -$STD uv venv /opt/.venv -export PATH="/opt/.venv/bin:$PATH" -source /opt/.venv/bin/activate -$STD uv pip install --upgrade pip -$STD uv pip install \ - opencv-python-headless \ - ocrmypdf \ - pillow \ - pdf2image - -$STD apt-get install -y python3-uno python3-pip -$STD pip3 install --break-system-packages unoserver -ln -sf /opt/.venv/bin/python3 /usr/local/bin/python3 -ln -sf /opt/.venv/bin/pip /usr/local/bin/pip -msg_ok "Installed Python Dependencies" - -msg_info "Installing JBIG2" -$STD curl -fsSL -o /tmp/jbig2enc.tar.gz https://github.com/agl/jbig2enc/archive/refs/tags/0.30.tar.gz -mkdir -p /opt/jbig2enc -tar -xzf /tmp/jbig2enc.tar.gz -C /opt/jbig2enc --strip-components=1 -cd /opt/jbig2enc -$STD bash ./autogen.sh -$STD bash ./configure -$STD make -$STD make install -msg_ok "Installed JBIG2" - -msg_info "Installing Language Packs (Patience)" -$STD apt-get install -y 'tesseract-ocr-*' -msg_ok "Installed Language Packs" - -msg_info "Creating Environment Variables" -cat </opt/Stirling-PDF/.env -# Java tuning -JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" -JAVA_CUSTOM_OPTS="" - -# LibreOffice -PATH=/opt/.venv/bin:/usr/lib/libreoffice/program:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -UNO_PATH=/usr/lib/libreoffice/program -URE_BOOTSTRAP=file:///usr/lib/libreoffice/program/fundamentalrc -PYTHONPATH=/usr/lib/libreoffice/program:/opt/.venv/lib/python3.12/site-packages -LD_LIBRARY_PATH=/usr/lib/libreoffice/program - -STIRLING_TEMPFILES_DIRECTORY=/tmp/stirling-pdf -TMPDIR=/tmp/stirling-pdf -TEMP=/tmp/stirling-pdf -TMP=/tmp/stirling-pdf - -# Paths -PATH=/opt/.venv/bin:/usr/lib/libreoffice/program:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -EOF - -if [[ "$login_mode" == "true" ]]; then - cat <>/opt/Stirling-PDF/.env -# activate Login -DISABLE_ADDITIONAL_FEATURES=false -SECURITY_ENABLELOGIN=true - -# login credentials -SECURITY_INITIALLOGIN_USERNAME=admin -SECURITY_INITIALLOGIN_PASSWORD=stirling -EOF -fi -msg_ok "Created Environment Variables" - -msg_info "Refreshing Font Cache" -$STD fc-cache -fv -msg_ok "Font Cache Updated" - -msg_info "Creating Service" -cat </etc/systemd/system/libreoffice-listener.service -[Unit] -Description=LibreOffice Headless Listener Service -After=network.target - -[Service] -Type=simple -User=root -Group=root -ExecStart=/usr/lib/libreoffice/program/soffice --headless --invisible --nodefault --nofirststartwizard --nolockcheck --nologo --accept="socket,host=127.0.0.1,port=2002;urp;StarOffice.ComponentContext" -Restart=always - -[Install] -WantedBy=multi-user.target -EOF - -cat </etc/systemd/system/stirlingpdf.service -[Unit] -Description=Stirling-PDF service -After=syslog.target network.target libreoffice-listener.service -Requires=libreoffice-listener.service - -[Service] -SuccessExitStatus=143 -Type=simple -User=root -Group=root -EnvironmentFile=/opt/Stirling-PDF/.env -WorkingDirectory=/opt/Stirling-PDF -ExecStart=/usr/bin/java -jar Stirling-PDF.jar -ExecStop=/bin/kill -15 %n -Restart=always -RestartSec=10 - -[Install] -WantedBy=multi-user.target -EOF - -cat </etc/systemd/system/unoserver.service -[Unit] -Description=UnoServer RPC Interface -After=libreoffice-listener.service -Requires=libreoffice-listener.service - -[Service] -Type=simple -ExecStart=/usr/local/bin/unoserver --port 2003 --interface 127.0.0.1 -Restart=always -EnvironmentFile=/opt/Stirling-PDF/.env - -[Install] -WantedBy=multi-user.target -EOF - -systemctl enable -q --now libreoffice-listener -systemctl enable -q --now stirlingpdf -systemctl enable -q --now unoserver -msg_ok "Created Service" - -motd_ssh -customize - -msg_info "Cleaning up" -rm -f /tmp/jbig2enc.tar.gz -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" diff --git a/install/trilium-install.sh b/install/trilium-install.sh deleted file mode 100644 index f5ddd078..00000000 --- a/install/trilium-install.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/TriliumNext/Trilium - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -fetch_and_deploy_gh_release "Trilium" "TriliumNext/Trilium" "prebuild" "latest" "/opt/trilium" "TriliumNotes-Server-*linux-x64.tar.xz" - -msg_info "Creating Service" -cat </etc/systemd/system/trilium.service -[Unit] -Description=Trilium Daemon -After=syslog.target network.target - -[Service] -User=root -Type=simple -ExecStart=/opt/trilium/trilium.sh -WorkingDirectory=/opt/trilium/ -TimeoutStopSec=20 -Restart=always - -[Install] -WantedBy=multi-user.target -EOF -systemctl enable --now -q trilium -msg_ok "Created Service" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" From f189fa3a8351f49d66a68d75bc070b56368e9a7e Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Thu, 10 Jul 2025 08:53:01 +0000 Subject: [PATCH 275/463] Update .app files (#696) Co-authored-by: GitHub Actions --- ct/headers/ersatztv | 6 ------ ct/headers/openwebui | 6 ------ ct/headers/stirling-pdf | 6 ------ ct/headers/trilium | 6 ------ 4 files changed, 24 deletions(-) delete mode 100644 ct/headers/ersatztv delete mode 100644 ct/headers/openwebui delete mode 100644 ct/headers/stirling-pdf delete mode 100644 ct/headers/trilium diff --git a/ct/headers/ersatztv b/ct/headers/ersatztv deleted file mode 100644 index f47317c3..00000000 --- a/ct/headers/ersatztv +++ /dev/null @@ -1,6 +0,0 @@ - ______ __ _______ __ - / ____/_____________ _/ /_____/_ __/ | / / - / __/ / ___/ ___/ __ `/ __/_ / / / | | / / - / /___/ / (__ ) /_/ / /_ / /_/ / | |/ / -/_____/_/ /____/\__,_/\__/ /___/_/ |___/ - diff --git a/ct/headers/openwebui b/ct/headers/openwebui deleted file mode 100644 index 0097a279..00000000 --- a/ct/headers/openwebui +++ /dev/null @@ -1,6 +0,0 @@ - ____ _ __ __ __ ______ - / __ \____ ___ ____ | | / /__ / /_ / / / / _/ - / / / / __ \/ _ \/ __ \ | | /| / / _ \/ __ \/ / / // / -/ /_/ / /_/ / __/ / / / | |/ |/ / __/ /_/ / /_/ // / -\____/ .___/\___/_/ /_/ |__/|__/\___/_.___/\____/___/ - /_/ diff --git a/ct/headers/stirling-pdf b/ct/headers/stirling-pdf deleted file mode 100644 index 1b7775bb..00000000 --- a/ct/headers/stirling-pdf +++ /dev/null @@ -1,6 +0,0 @@ - _____ __ _ ___ ____ ____ ______ - / ___// /_(_)____/ (_)___ ____ _ / __ \/ __ \/ ____/ - \__ \/ __/ / ___/ / / __ \/ __ `/_____/ /_/ / / / / /_ - ___/ / /_/ / / / / / / / / /_/ /_____/ ____/ /_/ / __/ -/____/\__/_/_/ /_/_/_/ /_/\__, / /_/ /_____/_/ - /____/ diff --git a/ct/headers/trilium b/ct/headers/trilium deleted file mode 100644 index 6f02b768..00000000 --- a/ct/headers/trilium +++ /dev/null @@ -1,6 +0,0 @@ - ______ _ ___ - /_ __/____(_) (_)_ ______ ___ - / / / ___/ / / / / / / __ `__ \ - / / / / / / / / /_/ / / / / / / -/_/ /_/ /_/_/_/\__,_/_/ /_/ /_/ - From 802cc6cc57bee2bae5862058119c20f169343ec7 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 11:42:41 +0200 Subject: [PATCH 276/463] Update healthchecks-install.sh --- install/healthchecks-install.sh | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/install/healthchecks-install.sh b/install/healthchecks-install.sh index 84ed2a52..f6708b66 100644 --- a/install/healthchecks-install.sh +++ b/install/healthchecks-install.sh @@ -15,15 +15,15 @@ update_os msg_info "Installing Dependencies" $STD apt-get install -y \ - gcc \ - libpq-dev \ - libcurl4-openssl-dev \ - libssl-dev + gcc \ + libpq-dev \ + libcurl4-openssl-dev \ + libssl-dev msg_ok "Installed Dependencies" msg_info "Setup Python3" $STD apt-get install -y \ - python3 python3-dev python3-pip + python3 python3-dev python3-pip $STD pip install --upgrade pip msg_ok "Setup Python3" @@ -42,23 +42,25 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8' $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'" { - echo "healthchecks-Credentials" - echo "healthchecks Database User: $DB_USER" - echo "healthchecks Database Password: $DB_PASS" - echo "healthchecks Database Name: $DB_NAME" + echo "healthchecks-Credentials" + echo "healthchecks Database User: $DB_USER" + echo "healthchecks Database Password: $DB_PASS" + echo "healthchecks Database Name: $DB_NAME" } >>~/healthchecks.creds msg_ok "Set up Database" msg_info "Setup healthchecks" fetch_and_deploy_gh_release "healthchecks" "healthchecks/healthchecks" "source" cd /opt/healthchecks +mkdir -p /opt/healthchecks/static-collected/ $STD uv venv .venv $STD source .venv/bin/activate $STD uv pip install wheel $STD uv pip install gunicorn $STD uv pip install -r requirements.txt +LOCAL_IP=$(hostname -I | awk '{print $1}') cat </opt/healthchecks/.env -ALLOWED_HOSTS=0.0.0.0 +ALLOWED_HOSTS=${LOCAL_IP},localhost,127.0.0.1 DB=postgres DB_HOST=localhost DB_PORT=5432 @@ -87,7 +89,8 @@ SITE_ROOT=http://0.0.0.0:8000 EOF $STD .venv/bin/python3 manage.py makemigrations -$STD .venv/bin/python3 manage.py migrate +$STD .venv/bin/python3 manage.py migrate --noinput +$STD .venv/bin/python3 manage.py collectstatic --noinput ADMIN_EMAIL="admin@helper-scripts.local" ADMIN_PASSWORD="$DB_PASS" From 0c19a50d919e5428df61a5ea1bc69f3f69e0fa9c Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 13:20:41 +0200 Subject: [PATCH 277/463] Update healthchecks-install.sh --- install/healthchecks-install.sh | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/install/healthchecks-install.sh b/install/healthchecks-install.sh index f6708b66..5476c3ff 100644 --- a/install/healthchecks-install.sh +++ b/install/healthchecks-install.sh @@ -60,7 +60,7 @@ $STD uv pip install gunicorn $STD uv pip install -r requirements.txt LOCAL_IP=$(hostname -I | awk '{print $1}') cat </opt/healthchecks/.env -ALLOWED_HOSTS=${LOCAL_IP},localhost,127.0.0.1 +ALLOWED_HOSTS=localhost,127.0.0.1,${LOCAL_IP},healthchecks DB=postgres DB_HOST=localhost DB_PORT=5432 @@ -81,11 +81,10 @@ EMAIL_USE_VERIFICATION=True # Django & Healthchecks Konfiguration SECRET_KEY=${SECRET_KEY} -DEBUG=False +DEBUG=True -SITE_ROOT=http://0.0.0.0:8000 +SITE_ROOT=http://${LOCAL_IP}:8000 SITE_NAME=Mychecks -SITE_ROOT=http://0.0.0.0:8000 EOF $STD .venv/bin/python3 manage.py makemigrations @@ -97,17 +96,8 @@ ADMIN_PASSWORD="$DB_PASS" cat < Date: Thu, 10 Jul 2025 14:33:01 +0200 Subject: [PATCH 278/463] qf: nodejs --- install/healthchecks-install.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/install/healthchecks-install.sh b/install/healthchecks-install.sh index 5476c3ff..5ce285fe 100644 --- a/install/healthchecks-install.sh +++ b/install/healthchecks-install.sh @@ -70,6 +70,7 @@ DB_PASSWORD=${DB_PASS} DB_CONN_MAX_AGE=0 DB_SSLMODE=prefer DB_TARGET_SESSION_ATTRS=read-write +DATABASE_URL=postgres://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}?sslmode=prefer DEFAULT_FROM_EMAIL=healthchecks@example.org EMAIL_HOST=localhost @@ -84,7 +85,9 @@ SECRET_KEY=${SECRET_KEY} DEBUG=True SITE_ROOT=http://${LOCAL_IP}:8000 -SITE_NAME=Mychecks +SITE_NAME=MyChecks +STATIC_ROOT=/opt/healthchecks/static-collected + EOF $STD .venv/bin/python3 manage.py makemigrations @@ -110,7 +113,8 @@ After=network.target postgresql.service [Service] WorkingDirectory=/opt/healthchecks/ EnvironmentFile=/opt/healthchecks/.env -ExecStart=/opt/healthchecks/.venv/bin/gunicorn hc.wsgi:application --bind 0.0.0.0 +ExecStart=/opt/healthchecks/.venv/bin/gunicorn hc.wsgi:application --bind 127.0.0.1:8000 + Restart=always [Install] From 82a09e00fb24b10954dfd5eaa05b2003036ee68d Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Thu, 10 Jul 2025 12:41:17 +0000 Subject: [PATCH 279/463] Update versions.json (#697) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 70 +++++++++++++++++++----------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 6a2867b3..dade0123 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,29 @@ [ + { + "name": "crowdsecurity/crowdsec", + "version": "v1.6.9", + "date": "2025-06-17T11:54:50Z" + }, + { + "name": "meilisearch/meilisearch", + "version": "prototype-incremental-vector-store-3", + "date": "2025-07-07T10:27:19Z" + }, + { + "name": "mattermost/mattermost", + "version": "preview-v0.1", + "date": "2025-06-27T14:35:47Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2140", + "date": "2025-07-10T05:54:59Z" + }, + { + "name": "firefly-iii/firefly-iii", + "version": "v6.2.20", + "date": "2025-07-02T04:03:37Z" + }, { "name": "steveiliop56/tinyauth", "version": "v3.6.0", @@ -74,11 +99,6 @@ "version": "v0.107.63", "date": "2025-06-26T14:34:19Z" }, - { - "name": "crowdsecurity/crowdsec", - "version": "v1.6.9", - "date": "2025-06-17T11:54:50Z" - }, { "name": "n8n-io/n8n", "version": "n8n@1.102.0", @@ -99,11 +119,6 @@ "version": "2025.6.3", "date": "2025-07-03T01:07:26Z" }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2135", - "date": "2025-07-09T05:58:50Z" - }, { "name": "MediaBrowser/Emby.Releases", "version": "4.9.1.2", @@ -164,11 +179,6 @@ "version": "coverity-w28-4.13.0", "date": "2025-07-08T11:25:24Z" }, - { - "name": "mattermost/mattermost", - "version": "preview-v0.1", - "date": "2025-06-27T14:35:47Z" - }, { "name": "docker/compose", "version": "v2.38.2", @@ -214,11 +224,6 @@ "version": "v25.05.2", "date": "2025-07-07T14:08:25Z" }, - { - "name": "meilisearch/meilisearch", - "version": "prototype-incremental-vector-store-3", - "date": "2025-07-07T10:27:19Z" - }, { "name": "Paymenter/Paymenter", "version": "v1.2.1", @@ -239,11 +244,6 @@ "version": "v1.5.2", "date": "2025-05-11T16:40:55Z" }, - { - "name": "firefly-iii/firefly-iii", - "version": "v6.2.20", - "date": "2025-07-02T04:03:37Z" - }, { "name": "slskd/slskd", "version": "0.23.1", @@ -463,5 +463,25 @@ "name": "jupyter/notebook", "version": "v7.4.4", "date": "2025-06-30T13:04:22Z" + }, + { + "name": "PrivateBin/PrivateBin", + "version": "1.7.8", + "date": "2025-06-30T09:00:54Z" + }, + { + "name": "typesense/typesense", + "version": "v29.0", + "date": "2025-06-30T03:52:33Z" + }, + { + "name": "dgtlmoon/changedetection.io", + "version": "0.50.5", + "date": "2025-06-29T08:54:47Z" + }, + { + "name": "plexguide/Huntarr.io", + "version": "8.1.11", + "date": "2025-06-28T03:42:46Z" } ] From a1262125a6bb3408b590f4510e0d1d30f312f26d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 14:44:00 +0200 Subject: [PATCH 280/463] Update tools.func --- misc/tools.func | 65 +++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 2b8a2a5b..bfa7e013 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -18,7 +18,6 @@ function setup_nodejs() { local CURRENT_NODE_VERSION="" local NEED_NODE_INSTALL=false - # Check if Node.js is already installed if command -v node >/dev/null; then CURRENT_NODE_VERSION="$(node -v | grep -oP '^v\K[0-9]+')" if [[ "$CURRENT_NODE_VERSION" != "$NODE_VERSION" ]]; then @@ -38,87 +37,99 @@ function setup_nodejs() { } fi - # Install Node.js if required if [[ "$NEED_NODE_INSTALL" == true ]]; then $STD apt-get purge -y nodejs - rm -f /etc/apt/sources.list.d/nodesource.list /etc/apt/keyrings/nodesource.gpg + rm -f /etc/apt/sources.list.d/nodesource.list /usr/share/keyrings/nodesource.gpg - mkdir -p /etc/apt/keyrings + mkdir -p /usr/share/keyrings + curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | + gpg --dearmor -o /usr/share/keyrings/nodesource.gpg || { + msg_error "Failed to import NodeSource GPG key" + exit 1 + } + chmod 644 /usr/share/keyrings/nodesource.gpg - if ! curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | - gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg; then - msg_error "Failed to download or import NodeSource GPG key" + local ARCH + ARCH=$(dpkg --print-architecture) + if ! [[ "$ARCH" =~ ^(amd64|arm64|armhf)$ ]]; then + msg_error "Unsupported architecture: $ARCH" exit 1 fi - echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_VERSION}.x nodistro main" \ - >/etc/apt/sources.list.d/nodesource.list + echo "deb [arch=$ARCH signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_VERSION}.x nodistro main" >/etc/apt/sources.list.d/nodesource.list + cat </etc/apt/preferences.d/nodejs +Package: nodejs +Pin: origin deb.nodesource.com +Pin-Priority: 700 +EOF + + sleep 2 if ! apt-get update >/dev/null 2>&1; then - msg_error "Failed to update APT repositories after adding NodeSource" - exit 1 + msg_warn "APT update failed – retrying in 5s" + sleep 5 + if ! apt-get update >/dev/null 2>&1; then + msg_error "Failed to update APT repositories after adding NodeSource" + exit 1 + fi fi - if ! apt-get install -y nodejs >/dev/null 2>&1; then + if ! apt-get install -y -t nodistro nodejs >/dev/null 2>&1; then msg_error "Failed to install Node.js ${NODE_VERSION} from NodeSource" + apt-cache policy nodejs | tee "$STD" exit 1 fi + $STD npm install -g npm@latest || { + msg_error "Failed to update npm to latest version" + } msg_ok "Setup Node.js ${NODE_VERSION}" fi export NODE_OPTIONS="--max-old-space-size=4096" - # Ensure valid working directory for npm (avoids uv_cwd error) - if [[ ! -d /opt ]]; then - mkdir -p /opt - fi + [[ -d /opt ]] || mkdir -p /opt cd /opt || { msg_error "Failed to set safe working directory before npm install" exit 1 } - # Install global Node modules if [[ -n "$NODE_MODULE" ]]; then IFS=',' read -ra MODULES <<<"$NODE_MODULE" for mod in "${MODULES[@]}"; do local MODULE_NAME MODULE_REQ_VERSION MODULE_INSTALLED_VERSION if [[ "$mod" == @*/*@* ]]; then - # Scoped package with version, e.g. @vue/cli-service@latest MODULE_NAME="${mod%@*}" MODULE_REQ_VERSION="${mod##*@}" elif [[ "$mod" == *"@"* ]]; then - # Unscoped package with version, e.g. yarn@latest MODULE_NAME="${mod%@*}" MODULE_REQ_VERSION="${mod##*@}" else - # No version specified MODULE_NAME="$mod" MODULE_REQ_VERSION="latest" fi - # Check if the module is already installed if npm list -g --depth=0 "$MODULE_NAME" >/dev/null 2>&1; then MODULE_INSTALLED_VERSION="$(npm list -g --depth=0 "$MODULE_NAME" | grep "$MODULE_NAME@" | awk -F@ '{print $2}' | tr -d '[:space:]')" if [[ "$MODULE_REQ_VERSION" != "latest" && "$MODULE_REQ_VERSION" != "$MODULE_INSTALLED_VERSION" ]]; then msg_info "Updating $MODULE_NAME from v$MODULE_INSTALLED_VERSION to v$MODULE_REQ_VERSION" - if ! $STD npm install -g "${MODULE_NAME}@${MODULE_REQ_VERSION}"; then + $STD npm install -g "${MODULE_NAME}@${MODULE_REQ_VERSION}" || { msg_error "Failed to update $MODULE_NAME to version $MODULE_REQ_VERSION" exit 1 - fi + } elif [[ "$MODULE_REQ_VERSION" == "latest" ]]; then msg_info "Updating $MODULE_NAME to latest version" - if ! $STD npm install -g "${MODULE_NAME}@latest"; then + $STD npm install -g "${MODULE_NAME}@latest" || { msg_error "Failed to update $MODULE_NAME to latest version" exit 1 - fi + } fi else msg_info "Installing $MODULE_NAME@$MODULE_REQ_VERSION" - if ! $STD npm install -g "${MODULE_NAME}@${MODULE_REQ_VERSION}"; then + $STD npm install -g "${MODULE_NAME}@${MODULE_REQ_VERSION}" || { msg_error "Failed to install $MODULE_NAME@$MODULE_REQ_VERSION" exit 1 - fi + } fi done msg_ok "Installed Node.js modules: $NODE_MODULE" From 8859c9be413ebaaf010d02f7f2d897c18df9b135 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 15:29:16 +0200 Subject: [PATCH 281/463] rybbit --- ct/rybbit.sh | 42 ++++++++++++++++++++++ install/rybbit-install.sh | 76 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 ct/rybbit.sh create mode 100644 install/rybbit-install.sh diff --git a/ct/rybbit.sh b/ct/rybbit.sh new file mode 100644 index 00000000..e9164be4 --- /dev/null +++ b/ct/rybbit.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://github.com/rybbit-io/rybbit + +APP="Rybbit" +var_tags="${var_tags:-analytics}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-2048}" +var_disk="${var_disk:-5}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +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 /var ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + msg_info "Updating $APP LXC" + $STD apt-get update + $STD apt-get -y upgrade + msg_ok "Updated $APP LXC" + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!" +msg_custom "🚀" "${GN}" "${APP} setup has been successfully initialized!" diff --git a/install/rybbit-install.sh b/install/rybbit-install.sh new file mode 100644 index 00000000..e0af122d --- /dev/null +++ b/install/rybbit-install.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://github.com/rybbit-io/rybbit + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + caddy \ + apt-transport-https \ + ca-certificates +msg_ok "Installed Dependencies" + +PG_VERSION=17 setup_postgresql +NODE_VERSION="20" NODE_MODULE="next" setup_nodejs + +msg_info "Setup Clickhouse Repository" +curl -fsSL 'https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key' | sudo gpg --dearmor -o /usr/share/keyrings/clickhouse-keyring.gpg +ARCH=$(dpkg --print-architecture) +echo "deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg arch=${ARCH}] https://packages.clickhouse.com/deb stable main" | sudo tee /etc/apt/sources.list.d/clickhouse.list +$STD apt-get update +$STD apt-get install -y clickhouse-server clickhouse-client +$STD systemctl enable --now clickhouse-server +sleep 3 +msg_ok "Set up Clickhouse Repository" + +msg_info "Setting up Clickhouse Database" +CLICKHOUSE_DB="${CLICKHOUSE_DB:-rybbit_db}" +CLICKHOUSE_USER="${CLICKHOUSE_USER:-rybbit}" +CLICKHOUSE_PASS="${CLICKHOUSE_PASS:-$(openssl rand -base64 18 | cut -c1-13)}" +CLICKHOUSE_HOST="localhost" + +clickhouse client --query "CREATE DATABASE IF NOT EXISTS $CLICKHOUSE_DB" +clickhouse client --query="CREATE USER IF NOT EXISTS $CLICKHOUSE_USER IDENTIFIED WITH plaintext_password BY '$CLICKHOUSE_PASS'" +clickhouse client --query="GRANT ALL ON $CLICKHOUSE_DB.* TO $CLICKHOUSE_USER" +#sed -i 's|default|read_only|' /etc/clickhouse-server/users.xml +#sed -i 's||DISABLED|' /etc/clickhouse-server/users.xml +$STD systemctl restart clickhouse-server +msg_ok "Set up Clickhouse Database" + +msg_info "Setting up PostgreSQL Database" +DB_NAME=rybbit_db +DB_USER=rybbit +DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" +APP_SECRET=$(openssl rand -base64 32) +$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" +$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'" +{ + echo "Rybbit-Credentials" + echo "Rybbit Database User: $DB_USER" + echo "Rybbit Database Password: $DB_PASS" + echo "Rybbit Database Name: $DB_NAME" +} >>~/rybbit.creds +msg_ok "Set up PostgreSQL Database" + +fetch_and_deploy_gh_release "rybbit" "rybbit-io/rybbit" "tarball" "latest" "/opt/rybbit" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 3f092a5ba53e878a1efa1afdf08e370484c84fcd Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Thu, 10 Jul 2025 13:29:46 +0000 Subject: [PATCH 282/463] Update .app files (#698) Co-authored-by: GitHub Actions --- ct/headers/rybbit | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ct/headers/rybbit diff --git a/ct/headers/rybbit b/ct/headers/rybbit new file mode 100644 index 00000000..f4726262 --- /dev/null +++ b/ct/headers/rybbit @@ -0,0 +1,6 @@ + ____ __ __ _ __ + / __ \__ __/ /_ / /_ (_) /_ + / /_/ / / / / __ \/ __ \/ / __/ + / _, _/ /_/ / /_/ / /_/ / / /_ +/_/ |_|\__, /_.___/_.___/_/\__/ + /____/ From 81b3f74c4d2d53cccd25e6d1b0ca5819c1c728f5 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 15:38:49 +0200 Subject: [PATCH 283/463] clickhouse --- install/rybbit-install.sh | 22 +-------------- misc/tools.func | 56 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 21 deletions(-) diff --git a/install/rybbit-install.sh b/install/rybbit-install.sh index e0af122d..0c8d8cc7 100644 --- a/install/rybbit-install.sh +++ b/install/rybbit-install.sh @@ -20,32 +20,12 @@ $STD apt-get install -y \ ca-certificates msg_ok "Installed Dependencies" +CLICKHOUSE_DB="rybbit_db" CLICKHOUSE_USER="rybbit" setup_clickhouse PG_VERSION=17 setup_postgresql NODE_VERSION="20" NODE_MODULE="next" setup_nodejs -msg_info "Setup Clickhouse Repository" -curl -fsSL 'https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key' | sudo gpg --dearmor -o /usr/share/keyrings/clickhouse-keyring.gpg -ARCH=$(dpkg --print-architecture) -echo "deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg arch=${ARCH}] https://packages.clickhouse.com/deb stable main" | sudo tee /etc/apt/sources.list.d/clickhouse.list -$STD apt-get update -$STD apt-get install -y clickhouse-server clickhouse-client -$STD systemctl enable --now clickhouse-server -sleep 3 -msg_ok "Set up Clickhouse Repository" - -msg_info "Setting up Clickhouse Database" -CLICKHOUSE_DB="${CLICKHOUSE_DB:-rybbit_db}" -CLICKHOUSE_USER="${CLICKHOUSE_USER:-rybbit}" -CLICKHOUSE_PASS="${CLICKHOUSE_PASS:-$(openssl rand -base64 18 | cut -c1-13)}" -CLICKHOUSE_HOST="localhost" - -clickhouse client --query "CREATE DATABASE IF NOT EXISTS $CLICKHOUSE_DB" -clickhouse client --query="CREATE USER IF NOT EXISTS $CLICKHOUSE_USER IDENTIFIED WITH plaintext_password BY '$CLICKHOUSE_PASS'" -clickhouse client --query="GRANT ALL ON $CLICKHOUSE_DB.* TO $CLICKHOUSE_USER" #sed -i 's|default|read_only|' /etc/clickhouse-server/users.xml #sed -i 's||DISABLED|' /etc/clickhouse-server/users.xml -$STD systemctl restart clickhouse-server -msg_ok "Set up Clickhouse Database" msg_info "Setting up PostgreSQL Database" DB_NAME=rybbit_db diff --git a/misc/tools.func b/misc/tools.func index bfa7e013..c34974c6 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1867,3 +1867,59 @@ function setup_ffmpeg() { ensure_usr_local_bin_persist msg_ok "Setup FFmpeg $FINAL_VERSION" } + +# ------------------------------------------------------------------------------ +# Installs ClickHouse server and client, sets up DB/user with credentials. +# +# Description: +# - Adds official ClickHouse APT repo with GPG key +# - Installs clickhouse-server and clickhouse-client +# - Creates database and user (credentials optionally overrideable via env) +# +# Variables: +# CLICKHOUSE_DB - Database name (default: analytics) +# CLICKHOUSE_USER - Username (default: analytics_user) +# CLICKHOUSE_PASS - Password (default: auto-generated) +# ------------------------------------------------------------------------------ + +function setup_clickhouse() { + local CLICKHOUSE_DB="${CLICKHOUSE_DB:-analytics}" + local CLICKHOUSE_USER="${CLICKHOUSE_USER:-analytics_user}" + local CLICKHOUSE_PASS="${CLICKHOUSE_PASS:-$(openssl rand -base64 18 | cut -c1-13)}" + local GPG_URL="https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key" + local GPG_KEY_PATH="/usr/share/keyrings/clickhouse-keyring.gpg" + local ARCH + ARCH=$(dpkg --print-architecture) + + msg_info "Adding ClickHouse repository" + if ! getent ahosts packages.clickhouse.com >/dev/null; then + msg_error "DNS resolution failed – possibly blocked (AdGuard, Pi-hole)" + return 1 + fi + + if ! curl -fsSL --connect-timeout 10 --retry 3 "$GPG_URL" | gpg --dearmor -o "$GPG_KEY_PATH"; then + msg_error "Failed to fetch ClickHouse GPG key" + return 1 + fi + + echo "deb [signed-by=$GPG_KEY_PATH arch=$ARCH] https://packages.clickhouse.com/deb stable main" >/etc/apt/sources.list.d/clickhouse.list + $STD apt-get update + + msg_info "Installing ClickHouse" + $STD apt-get install -y clickhouse-server clickhouse-client + $STD systemctl enable --now clickhouse-server + sleep 3 + msg_ok "Installed ClickHouse" + + msg_info "Creating ClickHouse DB '$CLICKHOUSE_DB' and user '$CLICKHOUSE_USER'" + clickhouse client --query "CREATE DATABASE IF NOT EXISTS $CLICKHOUSE_DB" + clickhouse client --query "CREATE USER IF NOT EXISTS $CLICKHOUSE_USER IDENTIFIED WITH plaintext_password BY '$CLICKHOUSE_PASS'" + clickhouse client --query "GRANT ALL ON $CLICKHOUSE_DB.* TO $CLICKHOUSE_USER" + msg_ok "Created DB and user" + + { + echo "ClickHouse DB: $CLICKHOUSE_DB" + echo "ClickHouse User: $CLICKHOUSE_USER" + echo "ClickHouse Pass: $CLICKHOUSE_PASS" + } >>~/clickhouse.creds +} From 05e24b3b7e16da0ef9a475c1ef7e09a922a695d8 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 15:43:00 +0200 Subject: [PATCH 284/463] Update tools.func --- misc/tools.func | 64 ++++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index c34974c6..eb027038 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1891,35 +1891,39 @@ function setup_clickhouse() { local ARCH ARCH=$(dpkg --print-architecture) - msg_info "Adding ClickHouse repository" - if ! getent ahosts packages.clickhouse.com >/dev/null; then - msg_error "DNS resolution failed – possibly blocked (AdGuard, Pi-hole)" - return 1 + if ! command -v clickhouse >/dev/null; then + msg_info "Setup ClickHouse" + if ! getent ahosts packages.clickhouse.com >/dev/null; then + msg_error "DNS resolution failed – possibly blocked (AdGuard, Pi-hole)" + return 1 + fi + + if ! curl -fsSL --connect-timeout 10 --retry 3 "$GPG_URL" | gpg --dearmor -o "$GPG_KEY_PATH"; then + msg_error "Failed to fetch ClickHouse GPG key" + return 1 + fi + + echo "deb [signed-by=$GPG_KEY_PATH arch=$ARCH] https://packages.clickhouse.com/deb stable main" >/etc/apt/sources.list.d/clickhouse.list + $STD apt-get update + + $STD apt-get install -y clickhouse-server clickhouse-client + $STD systemctl enable --now clickhouse-server + sleep 3 + + clickhouse client --query "CREATE DATABASE IF NOT EXISTS $CLICKHOUSE_DB" + clickhouse client --query "CREATE USER IF NOT EXISTS $CLICKHOUSE_USER IDENTIFIED WITH plaintext_password BY '$CLICKHOUSE_PASS'" + clickhouse client --query "GRANT ALL ON $CLICKHOUSE_DB.* TO $CLICKHOUSE_USER" + msg_ok "Setup ClickHouse" + + { + echo "ClickHouse DB: $CLICKHOUSE_DB" + echo "ClickHouse User: $CLICKHOUSE_USER" + echo "ClickHouse Pass: $CLICKHOUSE_PASS" + } >>~/clickhouse.creds + else + msg_info "Updating ClickHouse packages" + $STD apt-get update + $STD apt-get install -y --only-upgrade clickhouse-server clickhouse-client + msg_ok "ClickHouse updated" fi - - if ! curl -fsSL --connect-timeout 10 --retry 3 "$GPG_URL" | gpg --dearmor -o "$GPG_KEY_PATH"; then - msg_error "Failed to fetch ClickHouse GPG key" - return 1 - fi - - echo "deb [signed-by=$GPG_KEY_PATH arch=$ARCH] https://packages.clickhouse.com/deb stable main" >/etc/apt/sources.list.d/clickhouse.list - $STD apt-get update - - msg_info "Installing ClickHouse" - $STD apt-get install -y clickhouse-server clickhouse-client - $STD systemctl enable --now clickhouse-server - sleep 3 - msg_ok "Installed ClickHouse" - - msg_info "Creating ClickHouse DB '$CLICKHOUSE_DB' and user '$CLICKHOUSE_USER'" - clickhouse client --query "CREATE DATABASE IF NOT EXISTS $CLICKHOUSE_DB" - clickhouse client --query "CREATE USER IF NOT EXISTS $CLICKHOUSE_USER IDENTIFIED WITH plaintext_password BY '$CLICKHOUSE_PASS'" - clickhouse client --query "GRANT ALL ON $CLICKHOUSE_DB.* TO $CLICKHOUSE_USER" - msg_ok "Created DB and user" - - { - echo "ClickHouse DB: $CLICKHOUSE_DB" - echo "ClickHouse User: $CLICKHOUSE_USER" - echo "ClickHouse Pass: $CLICKHOUSE_PASS" - } >>~/clickhouse.creds } From 6ab87422a19bf33660dd98ef181656b034a31dc1 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 10 Jul 2025 15:47:09 +0200 Subject: [PATCH 285/463] Update tools.func --- misc/tools.func | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index eb027038..27b8c3ca 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1893,8 +1893,9 @@ function setup_clickhouse() { if ! command -v clickhouse >/dev/null; then msg_info "Setup ClickHouse" - if ! getent ahosts packages.clickhouse.com >/dev/null; then - msg_error "DNS resolution failed – possibly blocked (AdGuard, Pi-hole)" + if ! dig +short packages.clickhouse.com | grep -qE '^[0-9a-f:.]+$'; then + msg_error "DNS blocked: packages.clickhouse.com" + echo "💡 Likely blocked by AdGuard, Pi-hole or similar" return 1 fi From 95d85b8a084176c1fe1adc17805687920c49800a Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Fri, 11 Jul 2025 01:43:43 +0000 Subject: [PATCH 286/463] Update versions.json (#700) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 94 +++++++++++++++++------------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index dade0123..eef04d1e 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,8 +1,58 @@ [ + { + "name": "steveiliop56/tinyauth", + "version": "v3.6.0", + "date": "2025-07-09T23:15:25Z" + }, + { + "name": "jenkinsci/jenkins", + "version": "jenkins-2.518", + "date": "2025-07-08T13:52:55Z" + }, + { + "name": "rcourtman/Pulse", + "version": "v3.41.1", + "date": "2025-07-10T17:10:46Z" + }, + { + "name": "LibreTranslate/LibreTranslate", + "version": "v1.7.2", + "date": "2025-07-10T19:29:26Z" + }, + { + "name": "binwiederhier/ntfy", + "version": "v2.13.0", + "date": "2025-07-10T19:27:54Z" + }, + { + "name": "ollama/ollama", + "version": "v0.9.6", + "date": "2025-07-08T01:26:29Z" + }, + { + "name": "msgbyte/tianji", + "version": "v1.23.4", + "date": "2025-07-10T18:13:38Z" + }, + { + "name": "mongodb/mongo", + "version": "r6.0.25", + "date": "2025-07-10T16:59:44Z" + }, + { + "name": "forgejo/forgejo", + "version": "v11.0.3", + "date": "2025-07-10T13:12:00Z" + }, { "name": "crowdsecurity/crowdsec", - "version": "v1.6.9", - "date": "2025-06-17T11:54:50Z" + "version": "v1.6.10", + "date": "2025-07-10T12:04:30Z" + }, + { + "name": "neo4j/neo4j", + "version": "5.26.9", + "date": "2025-07-10T10:04:29Z" }, { "name": "meilisearch/meilisearch", @@ -24,11 +74,6 @@ "version": "v6.2.20", "date": "2025-07-02T04:03:37Z" }, - { - "name": "steveiliop56/tinyauth", - "version": "v3.6.0", - "date": "2025-07-09T23:15:25Z" - }, { "name": "pocket-id/pocket-id", "version": "v1.6.2", @@ -54,11 +99,6 @@ "version": "v1.13.6", "date": "2025-07-09T17:23:01Z" }, - { - "name": "msgbyte/tianji", - "version": "v1.23.3", - "date": "2025-07-09T16:39:30Z" - }, { "name": "hargata/lubelog", "version": "v1.4.9", @@ -144,11 +184,6 @@ "version": "v0.35.0", "date": "2025-05-21T18:00:32Z" }, - { - "name": "rcourtman/Pulse", - "version": "v3.40.1", - "date": "2025-07-08T21:06:54Z" - }, { "name": "grokability/snipe-it", "version": "v8.1.18", @@ -164,11 +199,6 @@ "version": "v5.20.0", "date": "2025-07-08T16:27:11Z" }, - { - "name": "jenkinsci/jenkins", - "version": "jenkins-2.518", - "date": "2025-07-08T13:52:55Z" - }, { "name": "bunkerity/bunkerweb", "version": "v1.6.2", @@ -189,16 +219,6 @@ "version": "v2.4.0p7", "date": "2025-07-08T05:51:08Z" }, - { - "name": "ollama/ollama", - "version": "v0.9.6", - "date": "2025-07-08T01:26:29Z" - }, - { - "name": "mongodb/mongo", - "version": "r8.0.12-rc0", - "date": "2025-07-07T23:35:35Z" - }, { "name": "TandoorRecipes/recipes", "version": "1.5.35", @@ -473,15 +493,5 @@ "name": "typesense/typesense", "version": "v29.0", "date": "2025-06-30T03:52:33Z" - }, - { - "name": "dgtlmoon/changedetection.io", - "version": "0.50.5", - "date": "2025-06-29T08:54:47Z" - }, - { - "name": "plexguide/Huntarr.io", - "version": "8.1.11", - "date": "2025-06-28T03:42:46Z" } ] From e1e73c079babf278046c5051a85ada1c0282f27f Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 11 Jul 2025 09:10:57 +0200 Subject: [PATCH 287/463] Update tools.func --- misc/tools.func | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 27b8c3ca..8326d49e 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1893,38 +1893,56 @@ function setup_clickhouse() { if ! command -v clickhouse >/dev/null; then msg_info "Setup ClickHouse" - if ! dig +short packages.clickhouse.com | grep -qE '^[0-9a-f:.]+$'; then - msg_error "DNS blocked: packages.clickhouse.com" - echo "💡 Likely blocked by AdGuard, Pi-hole or similar" + + # → Teste Erreichbarkeit + if ! curl -fsSL --connect-timeout 5 https://packages.clickhouse.com/ping >/dev/null 2>&1; then + msg_error "Connection to packages.clickhouse.com:443 failed – possibly blocked" + echo "💡 Check AdGuard/Pi-hole or firewall rules" return 1 fi - if ! curl -fsSL --connect-timeout 10 --retry 3 "$GPG_URL" | gpg --dearmor -o "$GPG_KEY_PATH"; then + # → Hole GPG-Key + if ! curl -fsSL --retry 3 --connect-timeout 10 "$GPG_URL" | + gpg --dearmor -o "$GPG_KEY_PATH"; then msg_error "Failed to fetch ClickHouse GPG key" return 1 fi - echo "deb [signed-by=$GPG_KEY_PATH arch=$ARCH] https://packages.clickhouse.com/deb stable main" >/etc/apt/sources.list.d/clickhouse.list - $STD apt-get update + echo "deb [signed-by=$GPG_KEY_PATH arch=$ARCH] https://packages.clickhouse.com/deb stable main" \ + >/etc/apt/sources.list.d/clickhouse.list - $STD apt-get install -y clickhouse-server clickhouse-client + # ────────────────────────────────────────────────────── + # hier unterdrückst du CLICKHOUSE_USER im Env, damit + # die Paket-Skripte nicht den Systemuser 'rybbit' anlegen: + env -u CLICKHOUSE_USER $STD apt-get update + env -u CLICKHOUSE_USER $STD apt-get install -y \ + clickhouse-server clickhouse-client + # ────────────────────────────────────────────────────── + + # jetzt läuft das Paket mit dem Standard-User 'clickhouse' $STD systemctl enable --now clickhouse-server sleep 3 + # → Erst­­installation der Tabelle und des DB-Users clickhouse client --query "CREATE DATABASE IF NOT EXISTS $CLICKHOUSE_DB" - clickhouse client --query "CREATE USER IF NOT EXISTS $CLICKHOUSE_USER IDENTIFIED WITH plaintext_password BY '$CLICKHOUSE_PASS'" - clickhouse client --query "GRANT ALL ON $CLICKHOUSE_DB.* TO $CLICKHOUSE_USER" - msg_ok "Setup ClickHouse" + clickhouse client --query \ + "CREATE USER IF NOT EXISTS $CLICKHOUSE_USER IDENTIFIED WITH plaintext_password BY '$CLICKHOUSE_PASS'" + clickhouse client --query \ + "GRANT ALL ON $CLICKHOUSE_DB.* TO $CLICKHOUSE_USER" + msg_ok "Setup ClickHouse (DB: $CLICKHOUSE_DB, User: $CLICKHOUSE_USER)" + + # → sichere Credentials zur Kontrolle { - echo "ClickHouse DB: $CLICKHOUSE_DB" - echo "ClickHouse User: $CLICKHOUSE_USER" - echo "ClickHouse Pass: $CLICKHOUSE_PASS" + echo "ClickHouse DB: $CLICKHOUSE_DB" + echo "ClickHouse User: $CLICKHOUSE_USER" + echo "ClickHouse Pass: $CLICKHOUSE_PASS" } >>~/clickhouse.creds else msg_info "Updating ClickHouse packages" - $STD apt-get update - $STD apt-get install -y --only-upgrade clickhouse-server clickhouse-client + env -u CLICKHOUSE_USER $STD apt-get update + env -u CLICKHOUSE_USER $STD apt-get install -y --only-upgrade \ + clickhouse-server clickhouse-client msg_ok "ClickHouse updated" fi } From 41959f83bdd01f525e4a216985feeb018117f192 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 11 Jul 2025 09:44:05 +0200 Subject: [PATCH 288/463] Docker Refactor --- ct/docker.sh | 92 ++++++++++++++++++++++++++++++ install/docker-install.sh | 114 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 ct/docker.sh create mode 100644 install/docker-install.sh diff --git a/ct/docker.sh b/ct/docker.sh new file mode 100644 index 00000000..123d0c7c --- /dev/null +++ b/ct/docker.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://www.docker.com/ + +APP="Docker" +var_tags="${var_tags:-docker}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-2048}" +var_disk="${var_disk:-4}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + + get_latest_release() { + curl -fsSL https://api.github.com/repos/"$1"/releases/latest | grep '"tag_name":' | cut -d'"' -f4 + } + + msg_info "Updating base system" + $STD apt-get update + $STD apt-get -y upgrade + msg_ok "Base system updated" + + msg_info "Updating Docker Engine" + $STD apt-get install --only-upgrade -y docker-ce docker-ce-cli containerd.io + msg_ok "Docker Engine updated" + + if [[ -f /usr/local/lib/docker/cli-plugins/docker-compose ]]; then + COMPOSE_BIN="/usr/local/lib/docker/cli-plugins/docker-compose" + COMPOSE_NEW_VERSION=$(get_latest_release "docker/compose") + msg_info "Updating Docker Compose to $COMPOSE_NEW_VERSION" + curl -fsSL "https://github.com/docker/compose/releases/download/${COMPOSE_NEW_VERSION}/docker-compose-$(uname -s)-$(uname -m)" \ + -o "$COMPOSE_BIN" + chmod +x "$COMPOSE_BIN" + msg_ok "Docker Compose updated" + fi + + if docker ps -a --format '{{.Names}}' | grep -q '^portainer$'; then + msg_info "Updating Portainer" + docker pull portainer/portainer-ce:latest + docker stop portainer && docker rm portainer + docker volume create portainer_data >/dev/null 2>&1 + $STD docker run -d \ + -p 8000:8000 \ + -p 9443:9443 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest + msg_ok "Updated Portainer" + fi + + if docker ps -a --format '{{.Names}}' | grep -q '^portainer_agent$'; then + msg_info "Updating Portainer Agent" + docker pull portainer/agent:latest + docker stop portainer_agent && docker rm portainer_agent + $STD docker run -d \ + -p 9001:9001 \ + --name=portainer_agent \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /var/lib/docker/volumes:/var/lib/docker/volumes \ + portainer/agent + msg_ok "Updated Portainer Agent" + fi + + msg_info "Cleaning up" + $STD apt-get -y autoremove + $STD apt-get -y autoclean + msg_ok "Cleanup complete" + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" diff --git a/install/docker-install.sh b/install/docker-install.sh new file mode 100644 index 00000000..238a8404 --- /dev/null +++ b/install/docker-install.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://www.docker.com/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +get_latest_release() { + curl -fsSL https://api.github.com/repos/"$1"/releases/latest | grep '"tag_name":' | cut -d'"' -f4 +} + +DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") +PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") +PORTAINER_AGENT_LATEST_VERSION=$(get_latest_release "portainer/agent") +DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") + +msg_info "Installing Docker $DOCKER_LATEST_VERSION" +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json +$STD sh <(curl -fsSL https://get.docker.com) +msg_ok "Installed Docker $DOCKER_LATEST_VERSION" + +read -r -p "${TAB3}Install Docker Compose v2 plugin? " prompt_compose +if [[ ${prompt_compose,,} =~ ^(y|yes)$ ]]; then + msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" + mkdir -p /usr/local/lib/docker/cli-plugins + curl -fsSL "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_LATEST_VERSION}/docker-compose-$(uname -s)-$(uname -m)" \ + -o /usr/local/lib/docker/cli-plugins/docker-compose + chmod +x /usr/local/lib/docker/cli-plugins/docker-compose + msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" +fi + +read -r -p "${TAB3}Would you like to add Portainer (UI)? " prompt +if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" + docker volume create portainer_data >/dev/null + $STD docker run -d \ + -p 8000:8000 \ + -p 9443:9443 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest + msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" +else + read -r -p "${TAB3}Would you like to install the Portainer Agent (for remote management)? " prompt_agent + if [[ ${prompt_agent,,} =~ ^(y|yes)$ ]]; then + msg_info "Installing Portainer Agent $PORTAINER_AGENT_LATEST_VERSION" + $STD docker run -d \ + -p 9001:9001 \ + --name portainer_agent \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /var/lib/docker/volumes:/var/lib/docker/volumes \ + portainer/agent + msg_ok "Installed Portainer Agent $PORTAINER_AGENT_LATEST_VERSION" + fi +fi + +read -r -p "${TAB3}Expose Docker TCP socket (insecure) ? [n = No, l = Local only (127.0.0.1), a = All interfaces (0.0.0.0)] : " socket_choice +case "${socket_choice,,}" in + l) + socket="tcp://127.0.0.1:2375" + ;; + a) + socket="tcp://0.0.0.0:2375" + ;; + *) + socket="" + ;; +esac + +if [[ -n "$socket" ]]; then + msg_info "Enabling Docker TCP socket on $socket" + $STD apt-get install -y jq + + tmpfile=$(mktemp) + jq --arg sock "$socket" '. + { "hosts": ["unix:///var/run/docker.sock", $sock] }' /etc/docker/daemon.json > "$tmpfile" && mv "$tmpfile" /etc/docker/daemon.json + + mkdir -p /etc/systemd/system/docker.service.d + cat < /etc/systemd/system/docker.service.d/override.conf +[Service] +ExecStart= +ExecStart=/usr/bin/dockerd +EOF + + $STD systemctl daemon-reexec + $STD systemctl daemon-reload + + if systemctl restart docker; then + msg_ok "Docker TCP socket available on $socket" + else + msg_error "Docker failed to restart. Check journalctl -xeu docker.service" + exit 1 + fi +fi + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 98bed7bce80c91d8da8ea72368fc1b6b5f81c549 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Fri, 11 Jul 2025 07:44:28 +0000 Subject: [PATCH 289/463] Update .app files (#701) Co-authored-by: GitHub Actions --- ct/headers/docker | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ct/headers/docker diff --git a/ct/headers/docker b/ct/headers/docker new file mode 100644 index 00000000..907ffbae --- /dev/null +++ b/ct/headers/docker @@ -0,0 +1,6 @@ + ____ __ + / __ \____ _____/ /_____ _____ + / / / / __ \/ ___/ //_/ _ \/ ___/ + / /_/ / /_/ / /__/ ,< / __/ / +/_____/\____/\___/_/|_|\___/_/ + From 2d1a71a1cc0ae5a2c002e3591594449e45f3019a Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Fri, 11 Jul 2025 12:39:45 +0000 Subject: [PATCH 290/463] Update versions.json (#702) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 100 +++++++++++++---------------- 1 file changed, 45 insertions(+), 55 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index eef04d1e..b94e6fa8 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,44 @@ [ + { + "name": "FlowiseAI/Flowise", + "version": "flowise@3.0.4", + "date": "2025-07-11T11:26:10Z" + }, + { + "name": "prometheus/prometheus", + "version": "v2.53.5", + "date": "2025-06-30T11:01:12Z" + }, + { + "name": "Paymenter/Paymenter", + "version": "v1.2.2", + "date": "2025-07-11T10:09:47Z" + }, + { + "name": "traefik/traefik", + "version": "v3.4.4", + "date": "2025-07-11T08:41:34Z" + }, + { + "name": "mattermost/mattermost", + "version": "preview-v0.1", + "date": "2025-06-27T14:35:47Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2145", + "date": "2025-07-11T05:49:32Z" + }, + { + "name": "documenso/documenso", + "version": "v1.12.2-rc.1", + "date": "2025-07-11T02:55:56Z" + }, + { + "name": "outline/outline", + "version": "v0.85.1", + "date": "2025-07-11T01:17:53Z" + }, { "name": "steveiliop56/tinyauth", "version": "v3.6.0", @@ -29,6 +69,11 @@ "version": "v0.9.6", "date": "2025-07-08T01:26:29Z" }, + { + "name": "keycloak/keycloak", + "version": "26.3.1", + "date": "2025-07-09T15:41:43Z" + }, { "name": "msgbyte/tianji", "version": "v1.23.4", @@ -59,16 +104,6 @@ "version": "prototype-incremental-vector-store-3", "date": "2025-07-07T10:27:19Z" }, - { - "name": "mattermost/mattermost", - "version": "preview-v0.1", - "date": "2025-06-27T14:35:47Z" - }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2140", - "date": "2025-07-10T05:54:59Z" - }, { "name": "firefly-iii/firefly-iii", "version": "v6.2.20", @@ -109,11 +144,6 @@ "version": "v2.1.0.123-2.1.0.123_canary_2025-07-09", "date": "2025-07-09T16:08:36Z" }, - { - "name": "keycloak/keycloak", - "version": "26.3.1", - "date": "2025-07-09T15:41:43Z" - }, { "name": "nicolargo/glances", "version": "v4.3.3", @@ -244,11 +274,6 @@ "version": "v25.05.2", "date": "2025-07-07T14:08:25Z" }, - { - "name": "Paymenter/Paymenter", - "version": "v1.2.1", - "date": "2025-07-07T10:11:26Z" - }, { "name": "nzbgetcom/nzbget", "version": "v25.2", @@ -369,11 +394,6 @@ "version": "6.3.1", "date": "2025-07-04T11:20:48Z" }, - { - "name": "outline/outline", - "version": "v0.85.0", - "date": "2025-07-04T00:06:47Z" - }, { "name": "cloudflare/cloudflared", "version": "2025.7.0", @@ -399,11 +419,6 @@ "version": "v25.7.1", "date": "2025-07-03T01:03:18Z" }, - { - "name": "documenso/documenso", - "version": "v1.12.2-rc.0", - "date": "2025-07-03T00:31:22Z" - }, { "name": "Koenkk/zigbee2mqtt", "version": "2.5.1", @@ -468,30 +483,5 @@ "name": "MagicMirrorOrg/MagicMirror", "version": "v2.32.0", "date": "2025-06-30T22:12:48Z" - }, - { - "name": "jhuckaby/Cronicle", - "version": "v0.9.81", - "date": "2025-06-30T16:40:33Z" - }, - { - "name": "prometheus/prometheus", - "version": "v2.53.5", - "date": "2025-06-30T11:01:12Z" - }, - { - "name": "jupyter/notebook", - "version": "v7.4.4", - "date": "2025-06-30T13:04:22Z" - }, - { - "name": "PrivateBin/PrivateBin", - "version": "1.7.8", - "date": "2025-06-30T09:00:54Z" - }, - { - "name": "typesense/typesense", - "version": "v29.0", - "date": "2025-06-30T03:52:33Z" } ] From a28ff8fc9f38eb60a60128eb2b804577cb863652 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Sat, 12 Jul 2025 01:44:38 +0000 Subject: [PATCH 291/463] Update versions.json (#703) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 117 ++++++++++++++++------------- 1 file changed, 66 insertions(+), 51 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index b94e6fa8..0e4c9956 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,8 +1,73 @@ [ + { + "name": "blakeblackshear/frigate", + "version": "v0.14.1", + "date": "2024-08-29T22:32:51Z" + }, + { + "name": "steveiliop56/tinyauth", + "version": "v3.6.0", + "date": "2025-07-09T23:15:25Z" + }, + { + "name": "Ombi-app/Ombi", + "version": "v4.47.1", + "date": "2025-01-05T21:14:23Z" + }, + { + "name": "eclipse-mosquitto/mosquitto", + "version": "v2.0.22", + "date": "2025-07-11T21:34:20Z" + }, + { + "name": "mongodb/mongo", + "version": "r8.2.0-alpha0", + "date": "2025-07-11T21:06:26Z" + }, + { + "name": "duplicati/duplicati", + "version": "v2.1.0.124-2.1.0.124_canary_2025-07-11", + "date": "2025-07-11T20:09:08Z" + }, + { + "name": "TandoorRecipes/recipes", + "version": "1.5.35", + "date": "2025-06-22T08:30:10Z" + }, + { + "name": "MediaBrowser/Emby.Releases", + "version": "4.9.1.2", + "date": "2025-06-26T22:08:00Z" + }, + { + "name": "homarr-labs/homarr", + "version": "v1.28.0", + "date": "2025-07-11T19:16:26Z" + }, + { + "name": "keycloak/keycloak", + "version": "26.3.1", + "date": "2025-07-09T15:41:43Z" + }, + { + "name": "n8n-io/n8n", + "version": "n8n@1.101.2", + "date": "2025-07-11T12:03:41Z" + }, { "name": "FlowiseAI/Flowise", "version": "flowise@3.0.4", - "date": "2025-07-11T11:26:10Z" + "date": "2025-07-11T13:26:54Z" + }, + { + "name": "zwave-js/zwave-js-ui", + "version": "v10.9.0", + "date": "2025-07-11T12:57:54Z" + }, + { + "name": "zitadel/zitadel", + "version": "v3.3.1", + "date": "2025-07-11T11:51:48Z" }, { "name": "prometheus/prometheus", @@ -39,11 +104,6 @@ "version": "v0.85.1", "date": "2025-07-11T01:17:53Z" }, - { - "name": "steveiliop56/tinyauth", - "version": "v3.6.0", - "date": "2025-07-09T23:15:25Z" - }, { "name": "jenkinsci/jenkins", "version": "jenkins-2.518", @@ -69,21 +129,11 @@ "version": "v0.9.6", "date": "2025-07-08T01:26:29Z" }, - { - "name": "keycloak/keycloak", - "version": "26.3.1", - "date": "2025-07-09T15:41:43Z" - }, { "name": "msgbyte/tianji", "version": "v1.23.4", "date": "2025-07-10T18:13:38Z" }, - { - "name": "mongodb/mongo", - "version": "r6.0.25", - "date": "2025-07-10T16:59:44Z" - }, { "name": "forgejo/forgejo", "version": "v11.0.3", @@ -139,11 +189,6 @@ "version": "v1.4.9", "date": "2025-07-09T16:27:46Z" }, - { - "name": "duplicati/duplicati", - "version": "v2.1.0.123-2.1.0.123_canary_2025-07-09", - "date": "2025-07-09T16:08:36Z" - }, { "name": "nicolargo/glances", "version": "v4.3.3", @@ -169,11 +214,6 @@ "version": "v0.107.63", "date": "2025-06-26T14:34:19Z" }, - { - "name": "n8n-io/n8n", - "version": "n8n@1.102.0", - "date": "2025-07-07T15:32:29Z" - }, { "name": "fuma-nama/fumadocs", "version": "fumadocs-ui@15.6.3", @@ -189,11 +229,6 @@ "version": "2025.6.3", "date": "2025-07-03T01:07:26Z" }, - { - "name": "MediaBrowser/Emby.Releases", - "version": "4.9.1.2", - "date": "2025-06-26T22:08:00Z" - }, { "name": "henrygd/beszel", "version": "v0.11.1", @@ -249,11 +284,6 @@ "version": "v2.4.0p7", "date": "2025-07-08T05:51:08Z" }, - { - "name": "TandoorRecipes/recipes", - "version": "1.5.35", - "date": "2025-06-22T08:30:10Z" - }, { "name": "VictoriaMetrics/VictoriaMetrics", "version": "pmm-6401-v1.121.0", @@ -279,11 +309,6 @@ "version": "v25.2", "date": "2025-07-04T08:21:42Z" }, - { - "name": "zwave-js/zwave-js-ui", - "version": "v10.8.0", - "date": "2025-07-07T08:37:45Z" - }, { "name": "morpheus65535/bazarr", "version": "v1.5.2", @@ -369,16 +394,6 @@ "version": "2025.7.1", "date": "2025-07-04T20:02:52Z" }, - { - "name": "homarr-labs/homarr", - "version": "v1.27.0", - "date": "2025-07-04T19:16:16Z" - }, - { - "name": "zitadel/zitadel", - "version": "v3.3.0", - "date": "2025-06-12T06:54:48Z" - }, { "name": "emqx/emqx", "version": "e6.0.0-M1.202507-alpha.1", From ce4daf0244aa49bb7ce91bf4be4e8658d4ce7da6 Mon Sep 17 00:00:00 2001 From: Bas van den Berg <74251551+bvdberg01@users.noreply.github.com> Date: Sat, 12 Jul 2025 09:54:17 +0200 Subject: [PATCH 292/463] Add script: OTS --- ct/ots.sh | 44 ++++++++++++++++++++++++++++++++ install/ots-install.sh | 57 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 ct/ots.sh create mode 100644 install/ots-install.sh diff --git a/ct/ots.sh b/ct/ots.sh new file mode 100644 index 00000000..d089bd80 --- /dev/null +++ b/ct/ots.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: BvdBerg01 +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://github.com/Luzifer/ots + +APP="OTS" +var_tags="${var_tags:-analytics}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-512}" +var_disk="${var_disk:-3}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +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/ots ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + msg_info "Updating $APP LXC" + $STD apt-get update + $STD apt-get -y upgrade + msg_ok "Updated $APP LXC" + 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}:3000${CL}" diff --git a/install/ots-install.sh b/install/ots-install.sh new file mode 100644 index 00000000..437e3010 --- /dev/null +++ b/install/ots-install.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://github.com/Luzifer/ots + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + caddy \ + apt-transport-https \ + ca-certificates +msg_ok "Installed Dependencies" + +msg_info "Installing OTS" +fetch_and_deploy_gh_release "ots" "Luzifer/ots" "tarball" "latest" "/opt/ots" "ots_linux_amd64.tgz" +cat </opt/ots/env" +LISTEN=0.0.0.0:3000 +REDIS_URL=redis://127.0.0.1:6379 +SECRET_EXPIRY=604800 +STORAGE_TYPE=redis +EOF +msg_ok "Installed OTS" + +msg_info "Creating Services" +cat </etc/systemd/system/ots.service +[Unit] +Description=One-Time-Secret Service +After=network-online.target +Requires=network-online.target + +[Service] +EnvironmentFile=/opt/ots/env +ExecStart=/opt/ots/ots +Restart=Always +RestartSecs=5 + +[Install] +WantedBy=multi-user.target +EOF +msg_ok "Created Services" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From ea39437e7742963cd6ba6bfc373c659f22f0d850 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Sat, 12 Jul 2025 07:54:39 +0000 Subject: [PATCH 293/463] Update .app files (#704) Co-authored-by: GitHub Actions --- ct/headers/ots | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ct/headers/ots diff --git a/ct/headers/ots b/ct/headers/ots new file mode 100644 index 00000000..64a5fc43 --- /dev/null +++ b/ct/headers/ots @@ -0,0 +1,6 @@ + ____ ___________ + / __ \/_ __/ ___/ + / / / / / / \__ \ +/ /_/ / / / ___/ / +\____/ /_/ /____/ + From 82537627d59a0469a35d28dc98358f7ce56c4892 Mon Sep 17 00:00:00 2001 From: tremor021 Date: Sat, 12 Jul 2025 12:56:09 +0200 Subject: [PATCH 294/463] garmin-grafana: Fix path --- ct/garmin-grafana.sh | 134 +++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/ct/garmin-grafana.sh b/ct/garmin-grafana.sh index fb0a5afa..7351ad00 100644 --- a/ct/garmin-grafana.sh +++ b/ct/garmin-grafana.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/raw/main/garmin-grafana/misc/build.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/raw/main/misc/build.func) # Copyright (c) 2021-2025 community-scripts ORG # Author: aliaksei135 # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE @@ -21,74 +21,74 @@ catch_errors # this only updates garmin-grafana, not influxdb or grafana, which are upgraded with apt function update_script() { - header_info - check_container_storage - check_container_resources + header_info + check_container_storage + check_container_resources - if [[ ! -d /opt/garmin-grafana/ ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - - RELEASE=$(curl -fsSL https://api.github.com/repos/arpanghosh8453/garmin-grafana/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - if [[ ! -d /opt/garmin-grafana/ ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then - msg_info "Stopping $APP" - systemctl stop garmin-grafana - systemctl stop grafana-server - systemctl stop influxdb - msg_ok "Stopped $APP" - - if [[ ! -f /opt/garmin-grafana/.env ]]; then - msg_error "No .env file found in /opt/garmin-grafana/.env" - exit - fi - source /opt/garmin-grafana/.env - if [[ -z "${INFLUXDB_USER}" || -z "${INFLUXDB_PASSWORD}" || -z "${INFLUXDB_NAME}" ]]; then - msg_error "INFLUXDB_USER, INFLUXDB_PASSWORD, or INFLUXDB_NAME not set in .env file" - exit - fi - - msg_info "Creating Backup" - tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" /opt/garmin-grafana/.garminconnect /opt/garmin-grafana/.env - mv /opt/garmin-grafana/ /opt/garmin-grafana-backup/ - msg_ok "Backup Created" - - msg_info "Updating $APP to v${RELEASE}" - curl -fsSL -o "${RELEASE}.zip" "https://github.com/arpanghosh8453/garmin-grafana/archive/refs/tags/${RELEASE}.zip" - unzip -q "${RELEASE}.zip" - mv "garmin-grafana-${RELEASE}/" "/opt/garmin-grafana" - rm -f "${RELEASE}.zip" - $STD uv sync --locked --project /opt/garmin-grafana/ - # shellcheck disable=SC2016 - sed -i 's/\${DS_GARMIN_STATS}/garmin_influxdb/g' /opt/garmin-grafana/Grafana_Dashboard/Garmin-Grafana-Dashboard.json - sed -i 's/influxdb:8086/localhost:8086/' /opt/garmin-grafana/Grafana_Datasource/influxdb.yaml - sed -i "s/influxdb_user/${INFLUXDB_USER}/" /opt/garmin-grafana/Grafana_Datasource/influxdb.yaml - sed -i "s/influxdb_secret_password/${INFLUXDB_PASSWORD}/" /opt/garmin-grafana/Grafana_Datasource/influxdb.yaml - sed -i "s/GarminStats/${INFLUXDB_NAME}/" /opt/garmin-grafana/Grafana_Datasource/influxdb.yaml - # Copy across grafana data - cp -r /opt/garmin-grafana/Grafana_Datasource/* /etc/grafana/provisioning/datasources - cp -r /opt/garmin-grafana/Grafana_Dashboard/* /etc/grafana/provisioning/dashboards - # Copy back the env and token files - cp /opt/garmin-grafana-backup/.env /opt/garmin-grafana/.env - cp -r /opt/garmin-grafana-backup/.garminconnect /opt/garmin-grafana/.garminconnect - msg_ok "Updated $APP to v${RELEASE}" - - msg_info "Starting $APP" - systemctl start garmin-grafana - systemctl start grafana-server - systemctl start influxdb - msg_ok "Started $APP" - - msg_info "Cleaning Up" - rm -rf /opt/garmin-grafana-backup - msg_ok "Cleanup Completed" - - echo "${RELEASE}" >/opt/${APP}_version.txt - msg_ok "Update Successful" - else - msg_ok "No update required. ${APP} is already at v${RELEASE}" - fi + if [[ ! -d /opt/garmin-grafana/ ]]; then + msg_error "No ${APP} Installation Found!" exit + fi + + RELEASE=$(curl -fsSL https://api.github.com/repos/arpanghosh8453/garmin-grafana/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + if [[ ! -d /opt/garmin-grafana/ ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + msg_info "Stopping $APP" + systemctl stop garmin-grafana + systemctl stop grafana-server + systemctl stop influxdb + msg_ok "Stopped $APP" + + if [[ ! -f /opt/garmin-grafana/.env ]]; then + msg_error "No .env file found in /opt/garmin-grafana/.env" + exit + fi + source /opt/garmin-grafana/.env + if [[ -z "${INFLUXDB_USER}" || -z "${INFLUXDB_PASSWORD}" || -z "${INFLUXDB_NAME}" ]]; then + msg_error "INFLUXDB_USER, INFLUXDB_PASSWORD, or INFLUXDB_NAME not set in .env file" + exit + fi + + msg_info "Creating Backup" + tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" /opt/garmin-grafana/.garminconnect /opt/garmin-grafana/.env + mv /opt/garmin-grafana/ /opt/garmin-grafana-backup/ + msg_ok "Backup Created" + + msg_info "Updating $APP to v${RELEASE}" + curl -fsSL -o "${RELEASE}.zip" "https://github.com/arpanghosh8453/garmin-grafana/archive/refs/tags/${RELEASE}.zip" + unzip -q "${RELEASE}.zip" + mv "garmin-grafana-${RELEASE}/" "/opt/garmin-grafana" + rm -f "${RELEASE}.zip" + $STD uv sync --locked --project /opt/garmin-grafana/ + # shellcheck disable=SC2016 + sed -i 's/\${DS_GARMIN_STATS}/garmin_influxdb/g' /opt/garmin-grafana/Grafana_Dashboard/Garmin-Grafana-Dashboard.json + sed -i 's/influxdb:8086/localhost:8086/' /opt/garmin-grafana/Grafana_Datasource/influxdb.yaml + sed -i "s/influxdb_user/${INFLUXDB_USER}/" /opt/garmin-grafana/Grafana_Datasource/influxdb.yaml + sed -i "s/influxdb_secret_password/${INFLUXDB_PASSWORD}/" /opt/garmin-grafana/Grafana_Datasource/influxdb.yaml + sed -i "s/GarminStats/${INFLUXDB_NAME}/" /opt/garmin-grafana/Grafana_Datasource/influxdb.yaml + # Copy across grafana data + cp -r /opt/garmin-grafana/Grafana_Datasource/* /etc/grafana/provisioning/datasources + cp -r /opt/garmin-grafana/Grafana_Dashboard/* /etc/grafana/provisioning/dashboards + # Copy back the env and token files + cp /opt/garmin-grafana-backup/.env /opt/garmin-grafana/.env + cp -r /opt/garmin-grafana-backup/.garminconnect /opt/garmin-grafana/.garminconnect + msg_ok "Updated $APP to v${RELEASE}" + + msg_info "Starting $APP" + systemctl start garmin-grafana + systemctl start grafana-server + systemctl start influxdb + msg_ok "Started $APP" + + msg_info "Cleaning Up" + rm -rf /opt/garmin-grafana-backup + msg_ok "Cleanup Completed" + + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Update Successful" + else + msg_ok "No update required. ${APP} is already at v${RELEASE}" + fi + exit } start From ff9df1503900356e73331fc1bd8115b59710c361 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Sat, 12 Jul 2025 12:37:04 +0000 Subject: [PATCH 295/463] Update versions.json (#706) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 85 ++++++++++++------------------ 1 file changed, 35 insertions(+), 50 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 0e4c9956..b4244bc5 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,9 @@ [ + { + "name": "rcourtman/Pulse", + "version": "v3.41.1", + "date": "2025-07-10T17:10:46Z" + }, { "name": "blakeblackshear/frigate", "version": "v0.14.1", @@ -9,6 +14,36 @@ "version": "v3.6.0", "date": "2025-07-09T23:15:25Z" }, + { + "name": "homarr-labs/homarr", + "version": "v1.28.1", + "date": "2025-07-12T08:50:59Z" + }, + { + "name": "fallenbagel/jellyseerr", + "version": "preview-seerr", + "date": "2025-07-12T08:15:55Z" + }, + { + "name": "leiweibau/Pi.Alert", + "version": "v2025-07-12", + "date": "2025-07-12T07:53:52Z" + }, + { + "name": "firefly-iii/firefly-iii", + "version": "v6.2.20", + "date": "2025-07-02T04:03:37Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2151", + "date": "2025-07-12T05:53:09Z" + }, + { + "name": "fuma-nama/fumadocs", + "version": "fumadocs-openapi@9.1.2", + "date": "2025-07-12T03:58:47Z" + }, { "name": "Ombi-app/Ombi", "version": "v4.47.1", @@ -39,11 +74,6 @@ "version": "4.9.1.2", "date": "2025-06-26T22:08:00Z" }, - { - "name": "homarr-labs/homarr", - "version": "v1.28.0", - "date": "2025-07-11T19:16:26Z" - }, { "name": "keycloak/keycloak", "version": "26.3.1", @@ -89,11 +119,6 @@ "version": "preview-v0.1", "date": "2025-06-27T14:35:47Z" }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2145", - "date": "2025-07-11T05:49:32Z" - }, { "name": "documenso/documenso", "version": "v1.12.2-rc.1", @@ -109,11 +134,6 @@ "version": "jenkins-2.518", "date": "2025-07-08T13:52:55Z" }, - { - "name": "rcourtman/Pulse", - "version": "v3.41.1", - "date": "2025-07-10T17:10:46Z" - }, { "name": "LibreTranslate/LibreTranslate", "version": "v1.7.2", @@ -154,11 +174,6 @@ "version": "prototype-incremental-vector-store-3", "date": "2025-07-07T10:27:19Z" }, - { - "name": "firefly-iii/firefly-iii", - "version": "v6.2.20", - "date": "2025-07-02T04:03:37Z" - }, { "name": "pocket-id/pocket-id", "version": "v1.6.2", @@ -214,11 +229,6 @@ "version": "v0.107.63", "date": "2025-06-26T14:34:19Z" }, - { - "name": "fuma-nama/fumadocs", - "version": "fumadocs-ui@15.6.3", - "date": "2025-07-09T09:28:42Z" - }, { "name": "cockpit-project/cockpit", "version": "342", @@ -354,11 +364,6 @@ "version": "8.0.3", "date": "2025-07-06T12:19:24Z" }, - { - "name": "fallenbagel/jellyseerr", - "version": "preview-OIDC", - "date": "2025-07-06T00:51:06Z" - }, { "name": "hyperion-project/hyperion.ng", "version": "2.1.1", @@ -478,25 +483,5 @@ "name": "HabitRPG/habitica", "version": "v5.37.1", "date": "2025-07-01T16:57:43Z" - }, - { - "name": "navidrome/navidrome", - "version": "v0.57.0", - "date": "2025-07-01T16:47:46Z" - }, - { - "name": "zabbix/zabbix", - "version": "7.4.0", - "date": "2025-07-01T04:36:51Z" - }, - { - "name": "openobserve/openobserve", - "version": "v0.15.0-rc3", - "date": "2025-07-01T04:09:37Z" - }, - { - "name": "MagicMirrorOrg/MagicMirror", - "version": "v2.32.0", - "date": "2025-06-30T22:12:48Z" } ] From a87440283732e40321d80a0ccc6a98cd5b6f525e Mon Sep 17 00:00:00 2001 From: vhsdream Date: Sat, 12 Jul 2025 08:50:46 -0400 Subject: [PATCH 296/463] Reactive-Resume --- ct/reactive-resume.sh | 100 ++++++++++++ frontend/public/json/reactive-resume.json | 36 +++++ install/reactive-resume-install.sh | 178 ++++++++++++++++++++++ 3 files changed, 314 insertions(+) create mode 100644 ct/reactive-resume.sh create mode 100644 frontend/public/json/reactive-resume.json create mode 100644 install/reactive-resume-install.sh diff --git a/ct/reactive-resume.sh b/ct/reactive-resume.sh new file mode 100644 index 00000000..b6d491ed --- /dev/null +++ b/ct/reactive-resume.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: vhsdream +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://rxresu.me + +APP="Reactive-Resume" +var_tags="${var_tags:-documents}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-3072}" +var_disk="${var_disk:-8}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + + if [[ ! -f /etc/systemd/system/Reactive-Resume.service ]]; then + msg_error "No $APP Installation Found!" + exit + fi + RELEASE=$(curl -fsSL https://api.github.com/repos/lazy-media/Reactive-Resume/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') + if [[ ! -f "$HOME"/.reactive-resume ]] || [[ "$RELEASE" != "$(cat "$HOME"/.reactive-resume)" ]]; then + msg_info "Stopping services" + systemctl stop Reactive-Resume + msg_ok "Stopped services" + + msg_info "Updating $APP to v${RELEASE}" + cp /opt/"$APP"/.env /opt/rxresume.env + fetch_and_deploy_gh_release "Reactive-Resume" "lazy-media/Reactive-Resume" + cd /opt/"$APP" + export PUPPETEER_SKIP_DOWNLOAD="true" + export NEXT_TELEMETRY_DISABLED=1 + export CI="true" + export NODE_ENV="production" + $STD pnpm install --frozen-lockfile + $STD pnpm run build + $STD pnpm run prisma:generate + mv /opt/rxresume.env /opt/"$APP"/.env + msg_ok "Updated $APP to v$RELEASE" + + msg_info "Updating Minio" + systemctl stop minio + cd /tmp + curl -fsSL https://dl.min.io/server/minio/release/linux-amd64/minio.deb -o minio.deb + $STD dpkg -i minio.deb + msg_ok "Updated Minio" + + msg_info "Updating Browserless (Patience)" + systemctl stop browserless + cp /opt/browserless/.env /opt/browserless.env + rm -rf browserless + brwsr_tmp=$(mktemp) + TAG=$(curl -fsSL https://api.github.com/repos/browserless/browserless/tags?per_page=1 | grep "name" | awk '{print substr($2, 3, length($2)-4) }') + curl -fsSL https://github.com/browserless/browserless/archive/refs/tags/v"$TAG".zip -O "$brwsr_tmp" + $STD unzip "$brwsr_tmp" + mv browserless-"$TAG"/ /opt/browserless + cd /opt/browserless + $STD npm install + rm -rf src/routes/{chrome,edge,firefox,webkit} + $STD node_modules/playwright-core/cli.js install --with-deps chromium + $STD npm run build + $STD npm run build:function + $STD npm prune production + mv /opt/browserless.env /opt/browserless/.env + msg_ok "Updated Browserless" + + msg_info "Restarting services" + systemctl start minio Reactive-Resume browserless + msg_ok "Restarted services" + + msg_info "Cleaning Up" + rm -f /tmp/minio.deb + rm -f "$brwsr_tmp" + msg_ok "Cleanup Completed" + + msg_ok "Update Successful" + else + msg_ok "No update required. $APP is already at v$RELEASE" + 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}http://${IP}:3000${CL}" diff --git a/frontend/public/json/reactive-resume.json b/frontend/public/json/reactive-resume.json new file mode 100644 index 00000000..5c99acfb --- /dev/null +++ b/frontend/public/json/reactive-resume.json @@ -0,0 +1,36 @@ +{ + "name": "Reactive Resume", + "slug": "reactive-resume", + "categories": [ + 12 + ], + "date_created": "2025-04-22", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 3000, + "documentation": "https://docs.rxresume.org/", + "website": "https://rxresume.org", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/png/reactive-resume-light.png", + "config_path": "/opt/reactive-resume/.env", + "description": "A one-of-a-kind resume builder that keeps your privacy in mind. Completely secure, customizable, portable, open-source and free forever.", + "install_methods": [ + { + "type": "default", + "script": "ct/reactive-resume.sh", + "resources": { + "cpu": 2, + "ram": 3072, + "hdd": 8, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} + diff --git a/install/reactive-resume-install.sh b/install/reactive-resume-install.sh new file mode 100644 index 00000000..0813be46 --- /dev/null +++ b/install/reactive-resume-install.sh @@ -0,0 +1,178 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: vhsdream +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://rxresu.me + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +cd /tmp +curl -fsSL https://dl.min.io/server/minio/release/linux-amd64/minio.deb -o minio.deb +$STD dpkg -i minio.deb +msg_ok "Installed Dependencies" + +PG_VERSION="16" PG_MODULES="common" setup_postgresql +NODE_VERSION="22" NODE_MODULE="pnpm@latest" setup_nodejs + +msg_info "Setting up Database" +DB_USER="rxresume" +DB_NAME="rxresume" +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) +$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH ENCRYPTED PASSWORD '$DB_PASS';" +$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;" +$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME to $DB_USER;" +$STD sudo -u postgres psql -c "ALTER USER $DB_USER WITH SUPERUSER;" +msg_ok "Set up Database" + +msg_info "Installing $APPLICATION" +MINIO_PASS=$(openssl rand -base64 48) +ACCESS_TOKEN=$(openssl rand -base64 48) +REFRESH_TOKEN=$(openssl rand -base64 48) +CHROME_TOKEN=$(openssl rand -hex 32) +LOCAL_IP=$(hostname -I | awk '{print $1}') +TAG=$(curl -fsSL https://api.github.com/repos/browserless/browserless/tags?per_page=1 | grep "name" | awk '{print substr($2, 3, length($2)-4) }') + +fetch_and_deploy_gh_release "Reactive-Resume" "lazy-media/Reactive-Resume" +cd /opt/"$APPLICATION" +# corepack enable +export CI="true" +export PUPPETEER_SKIP_DOWNLOAD="true" +export NODE_ENV="production" +export NEXT_TELEMETRY_DISABLED=1 +$STD pnpm install --frozen-lockfile +$STD pnpm run build +$STD pnpm install --prod --frozen-lockfile +$STD pnpm run prisma:generate +msg_ok "Installed $APPLICATION" + +msg_info "Installing Browserless (Patience)" +cd /tmp +curl -fsSL https://github.com/browserless/browserless/archive/refs/tags/v"$TAG".zip -o v"$TAG".zip +$STD unzip v"$TAG".zip +mv browserless-"$TAG" /opt/browserless +cd /opt/browserless +$STD npm install +rm -rf src/routes/{chrome,edge,firefox,webkit} +$STD node_modules/playwright-core/cli.js install --with-deps chromium +$STD npm run build +$STD npm run build:function +$STD npm prune production +msg_ok "Installed Browserless" + +msg_info "Configuring applications" +mkdir -p /opt/minio +cat </opt/minio/.env +MINIO_ROOT_USER="storageadmin" +MINIO_ROOT_PASSWORD="${MINIO_PASS}" +MINIO_VOLUMES=/opt/minio +MINIO_OPTS="--address :9000 --console-address 127.0.0.1:9001" +EOF +cat </opt/"$APPLICATION"/.env +NODE_ENV=production +PORT=3000 +PUBLIC_URL=http://${LOCAL_IP}:3000 +STORAGE_URL=http://${LOCAL_IP}:9000/rxresume +DATABASE_URL=postgresql://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}?schema=public +ACCESS_TOKEN_SECRET=${ACCESS_TOKEN} +REFRESH_TOKEN_SECRET=${REFRESH_TOKEN} +CHROME_PORT=8080 +CHROME_TOKEN=${CHROME_TOKEN} +CHROME_URL=ws://localhost:8080 +CHROME_IGNORE_HTTPS_ERRORS=true +MAIL_FROM=noreply@locahost +# SMTP_URL=smtp://username:password@smtp.server.mail:587 # +STORAGE_ENDPOINT=localhost +STORAGE_PORT=9000 +STORAGE_REGION=us-east-1 +STORAGE_BUCKET=rxresume +STORAGE_ACCESS_KEY=storageadmin +STORAGE_SECRET_KEY=${MINIO_PASS} +STORAGE_USE_SSL=false +STORAGE_SKIP_BUCKET_CHECK=false + +# GitHub (OAuth, Optional) +# GITHUB_CLIENT_ID= +# GITHUB_CLIENT_SECRET= +# GITHUB_CALLBACK_URL=http://localhost:5173/api/auth/github/callback + +# Google (OAuth, Optional) +# GOOGLE_CLIENT_ID= +# GOOGLE_CLIENT_SECRET= +# GOOGLE_CALLBACK_URL=http://localhost:5173/api/auth/google/callback +EOF +cat </opt/browserless/.env +DEBUG=browserless*,-**:verbose +HOST=localhost +PORT=8080 +TOKEN=${CHROME_TOKEN} +EOF +{ + echo "${APPLICATION} Credentials" + echo "Database User: $DB_USER" + echo "Database Password: $DB_PASS" + echo "Database Name: $DB_NAME" + echo "Minio Root Password: ${MINIO_PASS}" +} >>~/"$APPLICATION".creds +msg_ok "Configured applications" + +msg_info "Creating Services" +mkdir -p /etc/systemd/system/minio.service.d/ +cat </etc/systemd/system/minio.service.d/override.conf +[Service] +User=root +Group=root +WorkingDirectory=/usr/local/bin +EnvironmentFile=/opt/minio/.env +EOF + +cat </etc/systemd/system/"$APPLICATION".service +[Unit] +Description=${APPLICATION} Service +After=network.target postgresql.service minio.service +Wants=postgresql.service minio.service + +[Service] +WorkingDirectory=/opt/${APPLICATION} +EnvironmentFile=/opt/${APPLICATION}/.env +ExecStart=/usr/bin/pnpm run start +Restart=always + +[Install] +WantedBy=multi-user.target +EOF + +cat </etc/systemd/system/browserless.service +[Unit] +Description=Browserless service +After=network.target ${APPLICATION}.service + +[Service] +WorkingDirectory=/opt/browserless +EnvironmentFile=/opt/browserless/.env +ExecStart=/usr/bin/npm run start +Restart=unless-stopped + +[Install] +WantedBy=multi-user.target +EOF +systemctl daemon-reload +systemctl enable -q --now minio.service "$APPLICATION".service browserless.service +msg_ok "Created Services" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -f /tmp/v"$TAG".zip +rm -f /tmp/minio.deb +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 0355001ea9cd03cc13391d13d70cce88d783d736 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Sat, 12 Jul 2025 12:51:15 +0000 Subject: [PATCH 297/463] Update .app files (#707) Co-authored-by: GitHub Actions --- ct/headers/reactive-resume | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ct/headers/reactive-resume diff --git a/ct/headers/reactive-resume b/ct/headers/reactive-resume new file mode 100644 index 00000000..e897791a --- /dev/null +++ b/ct/headers/reactive-resume @@ -0,0 +1,6 @@ + ____ __ _ ____ + / __ \___ ____ ______/ /_(_) _____ / __ \___ _______ ______ ___ ___ + / /_/ / _ \/ __ `/ ___/ __/ / | / / _ \______/ /_/ / _ \/ ___/ / / / __ `__ \/ _ \ + / _, _/ __/ /_/ / /__/ /_/ /| |/ / __/_____/ _, _/ __(__ ) /_/ / / / / / / __/ +/_/ |_|\___/\__,_/\___/\__/_/ |___/\___/ /_/ |_|\___/____/\__,_/_/ /_/ /_/\___/ + From ac60b04ea5ec5ecd5e46c21d36a3a7982e77b131 Mon Sep 17 00:00:00 2001 From: vhsdream Date: Sat, 12 Jul 2025 10:09:05 -0400 Subject: [PATCH 298/463] Reactive-Resume: Update source --- ct/reactive-resume.sh | 2 +- install/reactive-resume-install.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/reactive-resume.sh b/ct/reactive-resume.sh index b6d491ed..52a2fdce 100644 --- a/ct/reactive-resume.sh +++ b/ct/reactive-resume.sh @@ -3,7 +3,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV # Copyright (c) 2021-2025 community-scripts ORG # Author: vhsdream # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://rxresu.me +# Source: https://rxresume.org APP="Reactive-Resume" var_tags="${var_tags:-documents}" diff --git a/install/reactive-resume-install.sh b/install/reactive-resume-install.sh index 0813be46..895ace02 100644 --- a/install/reactive-resume-install.sh +++ b/install/reactive-resume-install.sh @@ -3,7 +3,7 @@ # Copyright (c) 2021-2025 community-scripts ORG # Author: vhsdream # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://rxresu.me +# Source: https://rxresume.org source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color From 898419f3775c4c0de0402df0cf83766bb6581b1e Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Sun, 13 Jul 2025 01:51:27 +0000 Subject: [PATCH 299/463] Update versions.json (#708) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 100 ++++++++++++----------------- 1 file changed, 40 insertions(+), 60 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index b4244bc5..32100224 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,44 @@ [ + { + "name": "esphome/esphome", + "version": "2025.6.3", + "date": "2025-07-03T01:07:26Z" + }, + { + "name": "steveiliop56/tinyauth", + "version": "v3.6.1", + "date": "2025-07-12T13:41:57Z" + }, + { + "name": "OliveTin/OliveTin", + "version": "2025.7.13", + "date": "2025-07-12T23:32:05Z" + }, + { + "name": "Ombi-app/Ombi", + "version": "v4.47.1", + "date": "2025-01-05T21:14:23Z" + }, + { + "name": "dgtlmoon/changedetection.io", + "version": "0.50.6", + "date": "2025-07-12T19:52:52Z" + }, + { + "name": "advplyr/audiobookshelf", + "version": "v2.26.0", + "date": "2025-07-12T19:31:21Z" + }, + { + "name": "jellyfin/jellyfin", + "version": "v10.10.7", + "date": "2025-04-05T19:14:59Z" + }, + { + "name": "cross-seed/cross-seed", + "version": "v6.13.0", + "date": "2025-07-12T15:52:03Z" + }, { "name": "rcourtman/Pulse", "version": "v3.41.1", @@ -9,11 +49,6 @@ "version": "v0.14.1", "date": "2024-08-29T22:32:51Z" }, - { - "name": "steveiliop56/tinyauth", - "version": "v3.6.0", - "date": "2025-07-09T23:15:25Z" - }, { "name": "homarr-labs/homarr", "version": "v1.28.1", @@ -44,11 +79,6 @@ "version": "fumadocs-openapi@9.1.2", "date": "2025-07-12T03:58:47Z" }, - { - "name": "Ombi-app/Ombi", - "version": "v4.47.1", - "date": "2025-01-05T21:14:23Z" - }, { "name": "eclipse-mosquitto/mosquitto", "version": "v2.0.22", @@ -234,11 +264,6 @@ "version": "342", "date": "2025-07-09T08:48:21Z" }, - { - "name": "esphome/esphome", - "version": "2025.6.3", - "date": "2025-07-03T01:07:26Z" - }, { "name": "henrygd/beszel", "version": "v0.11.1", @@ -374,11 +399,6 @@ "version": "v0.8.7", "date": "2025-07-05T20:08:58Z" }, - { - "name": "cross-seed/cross-seed", - "version": "v6.12.7", - "date": "2025-06-18T03:44:24Z" - }, { "name": "runtipi/runtipi", "version": "v4.3.0", @@ -443,45 +463,5 @@ "name": "Koenkk/zigbee2mqtt", "version": "2.5.1", "date": "2025-07-02T19:38:06Z" - }, - { - "name": "glpi-project/glpi", - "version": "10.0.18", - "date": "2025-02-12T11:07:02Z" - }, - { - "name": "apache/tomcat", - "version": "9.0.107", - "date": "2025-07-02T07:12:09Z" - }, - { - "name": "qbittorrent/qBittorrent", - "version": "release-5.1.2", - "date": "2025-07-02T06:13:16Z" - }, - { - "name": "diced/zipline", - "version": "v4.2.0", - "date": "2025-07-02T00:45:31Z" - }, - { - "name": "sysadminsmedia/homebox", - "version": "v0.20.2", - "date": "2025-07-02T00:37:07Z" - }, - { - "name": "Threadfin/Threadfin", - "version": "1.2.35", - "date": "2025-07-01T21:37:20Z" - }, - { - "name": "hivemq/hivemq-community-edition", - "version": "2025.4", - "date": "2025-07-01T18:01:37Z" - }, - { - "name": "HabitRPG/habitica", - "version": "v5.37.1", - "date": "2025-07-01T16:57:43Z" } ] From 3fc52224d7c201125e525e134a73414815abbabd Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Sun, 13 Jul 2025 12:37:42 +0000 Subject: [PATCH 300/463] Update versions.json (#710) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 60 ++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 32100224..d1c7e23c 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,24 @@ [ + { + "name": "rcourtman/Pulse", + "version": "v3.41.1", + "date": "2025-07-10T17:10:46Z" + }, + { + "name": "authelia/authelia", + "version": "v4.39.5", + "date": "2025-07-13T06:12:47Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2153", + "date": "2025-07-13T05:55:37Z" + }, + { + "name": "henrygd/beszel", + "version": "v0.11.1", + "date": "2025-04-29T01:14:35Z" + }, { "name": "esphome/esphome", "version": "2025.6.3", @@ -39,11 +59,6 @@ "version": "v6.13.0", "date": "2025-07-12T15:52:03Z" }, - { - "name": "rcourtman/Pulse", - "version": "v3.41.1", - "date": "2025-07-10T17:10:46Z" - }, { "name": "blakeblackshear/frigate", "version": "v0.14.1", @@ -64,16 +79,16 @@ "version": "v2025-07-12", "date": "2025-07-12T07:53:52Z" }, + { + "name": "keycloak/keycloak", + "version": "26.3.1", + "date": "2025-07-09T15:41:43Z" + }, { "name": "firefly-iii/firefly-iii", "version": "v6.2.20", "date": "2025-07-02T04:03:37Z" }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2151", - "date": "2025-07-12T05:53:09Z" - }, { "name": "fuma-nama/fumadocs", "version": "fumadocs-openapi@9.1.2", @@ -104,11 +119,6 @@ "version": "4.9.1.2", "date": "2025-06-26T22:08:00Z" }, - { - "name": "keycloak/keycloak", - "version": "26.3.1", - "date": "2025-07-09T15:41:43Z" - }, { "name": "n8n-io/n8n", "version": "n8n@1.101.2", @@ -264,11 +274,6 @@ "version": "342", "date": "2025-07-09T08:48:21Z" }, - { - "name": "henrygd/beszel", - "version": "v0.11.1", - "date": "2025-04-29T01:14:35Z" - }, { "name": "Prowlarr/Prowlarr", "version": "v1.37.0.5076", @@ -463,5 +468,20 @@ "name": "Koenkk/zigbee2mqtt", "version": "2.5.1", "date": "2025-07-02T19:38:06Z" + }, + { + "name": "glpi-project/glpi", + "version": "10.0.18", + "date": "2025-02-12T11:07:02Z" + }, + { + "name": "apache/tomcat", + "version": "9.0.107", + "date": "2025-07-02T07:12:09Z" + }, + { + "name": "qbittorrent/qBittorrent", + "version": "release-5.1.2", + "date": "2025-07-02T06:13:16Z" } ] From 87c733c419055f3cd94dd0780cfea5f97922f897 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 14 Jul 2025 01:47:40 +0000 Subject: [PATCH 301/463] Update versions.json (#711) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 80 +++++++++++++++--------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index d1c7e23c..49d435d9 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,44 @@ [ + { + "name": "steveiliop56/tinyauth", + "version": "v3.6.1", + "date": "2025-07-12T13:41:57Z" + }, + { + "name": "homebridge/homebridge", + "version": "v1.11.0", + "date": "2025-07-13T19:22:47Z" + }, + { + "name": "wavelog/wavelog", + "version": "2.0.6", + "date": "2025-07-13T19:10:15Z" + }, + { + "name": "MediaBrowser/Emby.Releases", + "version": "4.9.1.2", + "date": "2025-06-26T22:08:00Z" + }, + { + "name": "openhab/openhab-core", + "version": "5.0.0.M4", + "date": "2025-07-13T16:04:39Z" + }, + { + "name": "msgbyte/tianji", + "version": "v1.23.5", + "date": "2025-07-13T15:23:02Z" + }, + { + "name": "mayswind/AriaNg", + "version": "1.3.11", + "date": "2025-07-13T13:33:48Z" + }, + { + "name": "evcc-io/evcc", + "version": "0.205.0", + "date": "2025-07-13T12:27:31Z" + }, { "name": "rcourtman/Pulse", "version": "v3.41.1", @@ -24,11 +64,6 @@ "version": "2025.6.3", "date": "2025-07-03T01:07:26Z" }, - { - "name": "steveiliop56/tinyauth", - "version": "v3.6.1", - "date": "2025-07-12T13:41:57Z" - }, { "name": "OliveTin/OliveTin", "version": "2025.7.13", @@ -114,11 +149,6 @@ "version": "1.5.35", "date": "2025-06-22T08:30:10Z" }, - { - "name": "MediaBrowser/Emby.Releases", - "version": "4.9.1.2", - "date": "2025-06-26T22:08:00Z" - }, { "name": "n8n-io/n8n", "version": "n8n@1.101.2", @@ -189,11 +219,6 @@ "version": "v0.9.6", "date": "2025-07-08T01:26:29Z" }, - { - "name": "msgbyte/tianji", - "version": "v1.23.4", - "date": "2025-07-10T18:13:38Z" - }, { "name": "forgejo/forgejo", "version": "v11.0.3", @@ -458,30 +483,5 @@ "name": "Dolibarr/dolibarr", "version": "18.0.7", "date": "2025-07-03T08:57:21Z" - }, - { - "name": "actualbudget/actual", - "version": "v25.7.1", - "date": "2025-07-03T01:03:18Z" - }, - { - "name": "Koenkk/zigbee2mqtt", - "version": "2.5.1", - "date": "2025-07-02T19:38:06Z" - }, - { - "name": "glpi-project/glpi", - "version": "10.0.18", - "date": "2025-02-12T11:07:02Z" - }, - { - "name": "apache/tomcat", - "version": "9.0.107", - "date": "2025-07-02T07:12:09Z" - }, - { - "name": "qbittorrent/qBittorrent", - "version": "release-5.1.2", - "date": "2025-07-02T06:13:16Z" } ] From 5b7829d8f07eea90f451cb2b73af06a12666f18b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 08:58:50 +0200 Subject: [PATCH 302/463] Update delete-discord-thread.yml --- .github/workflows/delete-discord-thread.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/delete-discord-thread.yml b/.github/workflows/delete-discord-thread.yml index 19e36081..1c36059e 100644 --- a/.github/workflows/delete-discord-thread.yml +++ b/.github/workflows/delete-discord-thread.yml @@ -9,12 +9,12 @@ jobs: close_discord_thread: if: github.repository == 'community-scripts/ProxmoxVED' runs-on: ubuntu-latest + env: + ISSUE_TITLE: ${{ github.event.issue.title }} steps: - name: Get thread-ID op and close thread run: | - ISSUE_TITLE="${{ github.event.issue.title }}" - THREAD_ID=$(curl -s -X GET "https://discord.com/api/v10/guilds/${{ secrets.DISCORD_GUILD_ID }}/threads/active" \ -H "Authorization: Bot ${{ secrets.DISCORD_BOT_TOKEN }}" \ -H "Content-Type: application/json" | \ From e91bbdfb47fb66fc5068007f1dab3cd6f61d2908 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 09:59:56 +0200 Subject: [PATCH 303/463] Update mealie-install.sh --- install/mealie-install.sh | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/install/mealie-install.sh b/install/mealie-install.sh index 3e5d954f..210f4e06 100644 --- a/install/mealie-install.sh +++ b/install/mealie-install.sh @@ -17,19 +17,16 @@ msg_info "Installing Dependencies" $STD apt-get install -y build-essential libpq-dev libwebp-dev libsasl2-dev libldap2-dev libssl-dev git msg_ok "Installed Dependencies" -#fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball" "latest" "/opt/mealie" - deactivated for now - PYTHON_VERSION="3.12" setup_uv POSTGRES_VERSION="16" setup_postgresql NODE_MODULE="yarn" NODE_VERSION="20" setup_nodejs -msg_info "Setup Variables" +fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball" "latest" "/opt/mealie" + +msg_info "Setup Database" DB_NAME=mealie_db DB_USER=mealie__user DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13) -msg_ok "Set up Variables" - -msg_info "Setup Database" $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" @@ -44,11 +41,6 @@ $STD sudo -u postgres psql -c "ALTER USER $DB_USER WITH SUPERUSER;" } >>~/mealie.creds msg_ok "Set up Database" -msg_info "Get Mealie Repository" -cd /opt -$STD git clone https://github.com/mealie-recipes/mealie -msg_ok "Get Mealie Repository" - msg_info "Building Frontend" export NUXT_TELEMETRY_DISABLED=1 cd /opt/mealie/frontend From 6644d2541dcad71046bf738f0d03b635e7ca1f7a Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 10:12:40 +0200 Subject: [PATCH 304/463] Update mealie-install.sh --- install/mealie-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/mealie-install.sh b/install/mealie-install.sh index 210f4e06..566b3ab5 100644 --- a/install/mealie-install.sh +++ b/install/mealie-install.sh @@ -103,7 +103,7 @@ msg_ok "Built Wheel + Requirements" msg_info "Installing Mealie via uv" cd /opt/mealie -/opt/mealie/.venv/bin/uv pip install --require-hashes -r dist/requirements.txt --find-links dist +$STD /opt/mealie/.venv/bin/uv pip install --require-hashes -r /opt/mealie/dist/requirements.txt --find-links dist msg_ok "Installed Mealie" msg_info "Downloading NLTK Data" From e79c884fab5c97e32fe1dac4dcbf16898928279e Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 10:29:37 +0200 Subject: [PATCH 305/463] update --- ct/mealie.sh | 68 +++++++++++++++++++++++++++++++++++---- install/mealie-install.sh | 2 +- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/ct/mealie.sh b/ct/mealie.sh index d233296b..97a7f9ae 100644 --- a/ct/mealie.sh +++ b/ct/mealie.sh @@ -7,8 +7,8 @@ source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/ APP="Mealie" var_tags="${var_tags:-recipes}" -var_cpu="${var_cpu:-4}" -var_ram="${var_ram:-4096}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-2048}" var_disk="${var_disk:-10}" var_os="${var_os:-debian}" var_version="${var_version:-12}" @@ -23,14 +23,68 @@ function update_script() { header_info check_container_storage check_container_resources - if [[ ! -d /var ]]; then + + if [[ ! -d /opt/mealie ]]; then msg_error "No ${APP} Installation Found!" exit fi - msg_info "Updating $APP LXC" - $STD apt-get update - $STD apt-get -y upgrade - msg_ok "Updated $APP LXC" + + msg_info "Fetching Latest Release Version" + RELEASE=$(curl -fsSL https://api.github.com/repos/mealie-recipes/mealie/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+') + if [[ "${RELEASE}" != "$(cat ~/.mealie 2>/dev/null)" ]] || [[ ! -f ~/.mealie ]]; then + + PYTHON_VERSION="3.12" setup_uv + NODE_MODULE="yarn" NODE_VERSION="20" setup_nodejs + + msg_info "Stopping $APP" + systemctl stop mealie + msg_ok "Stopped $APP" + + msg_info "Backing up .env and start.sh" + cp -f /opt/mealie/mealie.env /opt/mealie/mealie.env.bak + cp -f /opt/mealie/start.sh /opt/mealie/start.sh.bak + msg_ok "Backup completed" + + fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball" "$RELEASE" "/opt/mealie" + + msg_info "Rebuilding Frontend" + export NUXT_TELEMETRY_DISABLED=1 + cd /opt/mealie/frontend + $STD yarn install --prefer-offline --frozen-lockfile --non-interactive --production=false --network-timeout 1000000 + $STD yarn generate + cp -r /opt/mealie/frontend/dist /opt/mealie/mealie/frontend + msg_ok "Frontend rebuilt" + + msg_info "Rebuilding Backend Environment" + cd /opt/mealie + $STD /opt/mealie/.venv/bin/poetry self add "poetry-plugin-export>=1.9" + MEALIE_VERSION=$(/opt/mealie/.venv/bin/poetry version --short) + $STD /opt/mealie/.venv/bin/poetry build --output dist + $STD /opt/mealie/.venv/bin/poetry export --only=main --extras=pgsql --output=dist/requirements.txt + echo "mealie[pgsql]==$MEALIE_VERSION \\" >>dist/requirements.txt + /opt/mealie/.venv/bin/poetry run pip hash dist/mealie-$MEALIE_VERSION*.whl | tail -n1 | tr -d '\n' >>dist/requirements.txt + echo " \\" >>dist/requirements.txt + /opt/mealie/.venv/bin/poetry run pip hash dist/mealie-$MEALIE_VERSION*.tar.gz | tail -n1 >>dist/requirements.txt + msg_ok "Backend prepared" + + msg_info "Installing Mealie $MEALIE_VERSION" + $STD /opt/mealie/.venv/bin/uv pip install --require-hashes -r /opt/mealie/dist/requirements.txt --find-links dist + msg_ok "Installed Mealie $MEALIE_VERSION" + + msg_info "Restoring Configuration" + mv -f /opt/mealie/mealie.env.bak /opt/mealie/mealie.env + mv -f /opt/mealie/start.sh.bak /opt/mealie/start.sh + chmod +x /opt/mealie/start.sh + msg_ok "Configuration restored" + + msg_info "Starting $APP" + systemctl start mealie + msg_ok "Started $APP" + + msg_ok "Update to $RELEASE Successful" + else + msg_ok "No update required. ${APP} is already at v${RELEASE}" + fi exit } diff --git a/install/mealie-install.sh b/install/mealie-install.sh index 566b3ab5..4d3e8292 100644 --- a/install/mealie-install.sh +++ b/install/mealie-install.sh @@ -2,7 +2,7 @@ # Copyright (c) 2021-2025 community-scripts ORG # Author: MickLesk (CanbiZ) -# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://mealie.io source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" From 84d971142a9fa10a278dd4d3a3dc54aad27063b4 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 10:49:30 +0200 Subject: [PATCH 306/463] Update mealie.sh --- ct/mealie.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ct/mealie.sh b/ct/mealie.sh index 97a7f9ae..30efdb20 100644 --- a/ct/mealie.sh +++ b/ct/mealie.sh @@ -29,8 +29,7 @@ function update_script() { exit fi - msg_info "Fetching Latest Release Version" - RELEASE=$(curl -fsSL https://api.github.com/repos/mealie-recipes/mealie/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+') + RELEASE=$(curl -fsSL https://api.github.com/repos/mealie-recipes/mealie/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+' | sed 's/^v//') if [[ "${RELEASE}" != "$(cat ~/.mealie 2>/dev/null)" ]] || [[ ! -f ~/.mealie ]]; then PYTHON_VERSION="3.12" setup_uv From 334d06ce4fb71f4a01ae2e407027b6d163466cfe Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 10:50:36 +0200 Subject: [PATCH 307/463] Update mealie.sh --- ct/mealie.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/mealie.sh b/ct/mealie.sh index 30efdb20..36d6add0 100644 --- a/ct/mealie.sh +++ b/ct/mealie.sh @@ -29,7 +29,7 @@ function update_script() { exit fi - RELEASE=$(curl -fsSL https://api.github.com/repos/mealie-recipes/mealie/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+' | sed 's/^v//') + RELEASE=$(curl -fsSL https://api.github.com/repos/mealie-recipes/mealie/releases/latest | jq -r '.tag_name | sub("^v"; "")') if [[ "${RELEASE}" != "$(cat ~/.mealie 2>/dev/null)" ]] || [[ ! -f ~/.mealie ]]; then PYTHON_VERSION="3.12" setup_uv From cdd45905001eccd13904a3beca16eee870bda2be Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 10:55:53 +0200 Subject: [PATCH 308/463] Update mealie.sh --- ct/mealie.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/mealie.sh b/ct/mealie.sh index 36d6add0..30efdb20 100644 --- a/ct/mealie.sh +++ b/ct/mealie.sh @@ -29,7 +29,7 @@ function update_script() { exit fi - RELEASE=$(curl -fsSL https://api.github.com/repos/mealie-recipes/mealie/releases/latest | jq -r '.tag_name | sub("^v"; "")') + RELEASE=$(curl -fsSL https://api.github.com/repos/mealie-recipes/mealie/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+' | sed 's/^v//') if [[ "${RELEASE}" != "$(cat ~/.mealie 2>/dev/null)" ]] || [[ ! -f ~/.mealie ]]; then PYTHON_VERSION="3.12" setup_uv From ff382397b628c040565e47e5b6b90ab2114d8570 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 10:57:37 +0200 Subject: [PATCH 309/463] Update mealie.sh --- ct/mealie.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/mealie.sh b/ct/mealie.sh index 30efdb20..7a40596c 100644 --- a/ct/mealie.sh +++ b/ct/mealie.sh @@ -29,8 +29,8 @@ function update_script() { exit fi - RELEASE=$(curl -fsSL https://api.github.com/repos/mealie-recipes/mealie/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+' | sed 's/^v//') - if [[ "${RELEASE}" != "$(cat ~/.mealie 2>/dev/null)" ]] || [[ ! -f ~/.mealie ]]; then + VERSION=$(curl -fsSL https://api.github.com/repos/mealie-recipes/mealie/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+' | sed 's/^v//') + if [[ "${VERSION}" != "$(cat ~/.mealie 2>/dev/null)" ]] || [[ ! -f ~/.mealie ]]; then PYTHON_VERSION="3.12" setup_uv NODE_MODULE="yarn" NODE_VERSION="20" setup_nodejs @@ -82,7 +82,7 @@ function update_script() { msg_ok "Update to $RELEASE Successful" else - msg_ok "No update required. ${APP} is already at v${RELEASE}" + msg_ok "No update required. ${APP} is already at v${VERSION}" fi exit } From 7f315eb3f831973f9e07ba4c84cb094321f18591 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 11:01:48 +0200 Subject: [PATCH 310/463] Update mealie.sh --- ct/mealie.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/mealie.sh b/ct/mealie.sh index 7a40596c..1f3dd394 100644 --- a/ct/mealie.sh +++ b/ct/mealie.sh @@ -29,8 +29,8 @@ function update_script() { exit fi - VERSION=$(curl -fsSL https://api.github.com/repos/mealie-recipes/mealie/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+' | sed 's/^v//') - if [[ "${VERSION}" != "$(cat ~/.mealie 2>/dev/null)" ]] || [[ ! -f ~/.mealie ]]; then + RELEASE=$(curl -fsSL https://api.github.com/repos/mealie-recipes/mealie/releases/latest | jq -r '.tag_name | sub("^v"; "")') + if [[ "${RELEASE}" != "$(cat ~/.mealie 2>/dev/null)" ]] || [[ ! -f ~/.mealie ]]; then PYTHON_VERSION="3.12" setup_uv NODE_MODULE="yarn" NODE_VERSION="20" setup_nodejs @@ -44,7 +44,7 @@ function update_script() { cp -f /opt/mealie/start.sh /opt/mealie/start.sh.bak msg_ok "Backup completed" - fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball" "$RELEASE" "/opt/mealie" + fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball" "latest" "/opt/mealie" msg_info "Rebuilding Frontend" export NUXT_TELEMETRY_DISABLED=1 @@ -82,7 +82,7 @@ function update_script() { msg_ok "Update to $RELEASE Successful" else - msg_ok "No update required. ${APP} is already at v${VERSION}" + msg_ok "No update required. ${APP} is already at v${RELEASE}" fi exit } From 0e749a30512a3007bc4e88f92d7d4024a8a95965 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 11:02:30 +0200 Subject: [PATCH 311/463] Update mealie.sh --- ct/mealie.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/mealie.sh b/ct/mealie.sh index 1f3dd394..e95a9851 100644 --- a/ct/mealie.sh +++ b/ct/mealie.sh @@ -66,9 +66,9 @@ function update_script() { /opt/mealie/.venv/bin/poetry run pip hash dist/mealie-$MEALIE_VERSION*.tar.gz | tail -n1 >>dist/requirements.txt msg_ok "Backend prepared" - msg_info "Installing Mealie $MEALIE_VERSION" + msg_info "Finalize Installation" $STD /opt/mealie/.venv/bin/uv pip install --require-hashes -r /opt/mealie/dist/requirements.txt --find-links dist - msg_ok "Installed Mealie $MEALIE_VERSION" + msg_ok "Mealie installed" msg_info "Restoring Configuration" mv -f /opt/mealie/mealie.env.bak /opt/mealie/mealie.env From 9b4698ff9753399e2a540b69ce8a2862edfe69aa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 14 Jul 2025 09:46:37 +0000 Subject: [PATCH 312/463] Deleted files for issue: Mealie --- ct/mealie.sh | 97 --------------------- frontend/public/json/mealie.json | 35 -------- install/mealie-install.sh | 143 ------------------------------- 3 files changed, 275 deletions(-) delete mode 100644 ct/mealie.sh delete mode 100644 frontend/public/json/mealie.json delete mode 100644 install/mealie-install.sh diff --git a/ct/mealie.sh b/ct/mealie.sh deleted file mode 100644 index e95a9851..00000000 --- a/ct/mealie.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env bash -source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) -# Copyright (c) 2021-2025 community-scripts ORG -# Author: MickLesk (CanbiZ) -# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE -# Source: https://mealie.io - -APP="Mealie" -var_tags="${var_tags:-recipes}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-2048}" -var_disk="${var_disk:-10}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -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/mealie ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - - RELEASE=$(curl -fsSL https://api.github.com/repos/mealie-recipes/mealie/releases/latest | jq -r '.tag_name | sub("^v"; "")') - if [[ "${RELEASE}" != "$(cat ~/.mealie 2>/dev/null)" ]] || [[ ! -f ~/.mealie ]]; then - - PYTHON_VERSION="3.12" setup_uv - NODE_MODULE="yarn" NODE_VERSION="20" setup_nodejs - - msg_info "Stopping $APP" - systemctl stop mealie - msg_ok "Stopped $APP" - - msg_info "Backing up .env and start.sh" - cp -f /opt/mealie/mealie.env /opt/mealie/mealie.env.bak - cp -f /opt/mealie/start.sh /opt/mealie/start.sh.bak - msg_ok "Backup completed" - - fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball" "latest" "/opt/mealie" - - msg_info "Rebuilding Frontend" - export NUXT_TELEMETRY_DISABLED=1 - cd /opt/mealie/frontend - $STD yarn install --prefer-offline --frozen-lockfile --non-interactive --production=false --network-timeout 1000000 - $STD yarn generate - cp -r /opt/mealie/frontend/dist /opt/mealie/mealie/frontend - msg_ok "Frontend rebuilt" - - msg_info "Rebuilding Backend Environment" - cd /opt/mealie - $STD /opt/mealie/.venv/bin/poetry self add "poetry-plugin-export>=1.9" - MEALIE_VERSION=$(/opt/mealie/.venv/bin/poetry version --short) - $STD /opt/mealie/.venv/bin/poetry build --output dist - $STD /opt/mealie/.venv/bin/poetry export --only=main --extras=pgsql --output=dist/requirements.txt - echo "mealie[pgsql]==$MEALIE_VERSION \\" >>dist/requirements.txt - /opt/mealie/.venv/bin/poetry run pip hash dist/mealie-$MEALIE_VERSION*.whl | tail -n1 | tr -d '\n' >>dist/requirements.txt - echo " \\" >>dist/requirements.txt - /opt/mealie/.venv/bin/poetry run pip hash dist/mealie-$MEALIE_VERSION*.tar.gz | tail -n1 >>dist/requirements.txt - msg_ok "Backend prepared" - - msg_info "Finalize Installation" - $STD /opt/mealie/.venv/bin/uv pip install --require-hashes -r /opt/mealie/dist/requirements.txt --find-links dist - msg_ok "Mealie installed" - - msg_info "Restoring Configuration" - mv -f /opt/mealie/mealie.env.bak /opt/mealie/mealie.env - mv -f /opt/mealie/start.sh.bak /opt/mealie/start.sh - chmod +x /opt/mealie/start.sh - msg_ok "Configuration restored" - - msg_info "Starting $APP" - systemctl start mealie - msg_ok "Started $APP" - - msg_ok "Update to $RELEASE Successful" - else - msg_ok "No update required. ${APP} is already at v${RELEASE}" - 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}http://${IP}:9000${CL}" diff --git a/frontend/public/json/mealie.json b/frontend/public/json/mealie.json deleted file mode 100644 index dbe8b4c4..00000000 --- a/frontend/public/json/mealie.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "Mealie", - "slug": "mealie", - "categories": [ - 13 - ], - "date_created": "2025-07-02", - "type": "ct", - "updateable": true, - "privileged": false, - "config_path": "/opt/mealie/.env", - "interface_port": 3000, - "documentation": "https://mealie.io/", - "website": "https://mealie.io/", - "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/mealie.svg", - "description": "Mealie is an open-source self-hosted application.", - "install_methods": [ - { - "type": "default", - "script": "ct/mealie.sh", - "resources": { - "cpu": 1, - "ram": 1024, - "hdd": 2, - "os": "Debian", - "version": "12" - } - } - ], - "default_credentials": { - "username": null, - "password": null - }, - "notes": [] -} \ No newline at end of file diff --git a/install/mealie-install.sh b/install/mealie-install.sh deleted file mode 100644 index 4d3e8292..00000000 --- a/install/mealie-install.sh +++ /dev/null @@ -1,143 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 community-scripts ORG -# Author: MickLesk (CanbiZ) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://mealie.io - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apt-get install -y build-essential libpq-dev libwebp-dev libsasl2-dev libldap2-dev libssl-dev git -msg_ok "Installed Dependencies" - -PYTHON_VERSION="3.12" setup_uv -POSTGRES_VERSION="16" setup_postgresql -NODE_MODULE="yarn" NODE_VERSION="20" setup_nodejs - -fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball" "latest" "/opt/mealie" - -msg_info "Setup Database" -DB_NAME=mealie_db -DB_USER=mealie__user -DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13) -$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" -$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;" -$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" -$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" -$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'" -$STD sudo -u postgres psql -c "ALTER USER $DB_USER WITH SUPERUSER;" -{ - echo "Mealie-Credentials" - echo "Mealie Database User: $DB_USER" - echo "Mealie Database Password: $DB_PASS" - echo "Mealie Database Name: $DB_NAME" -} >>~/mealie.creds -msg_ok "Set up Database" - -msg_info "Building Frontend" -export NUXT_TELEMETRY_DISABLED=1 -cd /opt/mealie/frontend -$STD yarn install --prefer-offline --frozen-lockfile --non-interactive --production=false --network-timeout 1000000 -$STD yarn generate -msg_ok "Built Frontend" - -msg_info "Copying Built Frontend into Backend Package" -cp -r /opt/mealie/frontend/dist /opt/mealie/mealie/frontend -msg_ok "Copied Frontend" - -msg_info "Preparing Backend (Poetry)" -$STD uv venv /opt/mealie/.venv -$STD /opt/mealie/.venv/bin/python -m ensurepip --upgrade -$STD /opt/mealie/.venv/bin/python -m pip install --upgrade pip -$STD /opt/mealie/.venv/bin/pip install uv -cd /opt/mealie -$STD /opt/mealie/.venv/bin/uv pip install poetry==2.0.1 -$STD /opt/mealie/.venv/bin/poetry self add "poetry-plugin-export>=1.9" -msg_ok "Prepared Poetry" - -msg_info "Writing Environment File" -cat </opt/mealie/mealie.env -HOST=0.0.0.0 -PORT=9000 -DB_ENGINE=postgres -POSTGRES_SERVER=localhost -POSTGRES_PORT=5432 -POSTGRES_USER=${DB_USER} -POSTGRES_PASSWORD=${DB_PASS} -POSTGRES_DB=${DB_NAME} -NLTK_DATA=/nltk_data -PRODUCTION=true -STATIC_FILES=/opt/mealie/frontend/dist -EOF -msg_ok "Wrote Environment File" - -msg_info "Creating Start Script" -cat <<'EOF' >/opt/mealie/start.sh -#!/bin/bash -set -a -source /opt/mealie/mealie.env -set +a -exec /opt/mealie/.venv/bin/mealie -EOF -chmod +x /opt/mealie/start.sh -msg_ok "Created Start Script" - -msg_info "Building Mealie Backend Wheel" -cd /opt/mealie -$STD /opt/mealie/.venv/bin/poetry build --output dist - -MEALIE_VERSION=$(/opt/mealie/.venv/bin/poetry version --short) -$STD /opt/mealie/.venv/bin/poetry export --only=main --extras=pgsql --output=dist/requirements.txt -echo "mealie[pgsql]==$MEALIE_VERSION \\" >>dist/requirements.txt -/opt/mealie/.venv/bin/poetry run pip hash dist/mealie-$MEALIE_VERSION*.whl | tail -n1 | tr -d '\n' >>dist/requirements.txt -echo " \\" >>dist/requirements.txt -/opt/mealie/.venv/bin/poetry run pip hash dist/mealie-$MEALIE_VERSION*.tar.gz | tail -n1 >>dist/requirements.txt -msg_ok "Built Wheel + Requirements" - -msg_info "Installing Mealie via uv" -cd /opt/mealie -$STD /opt/mealie/.venv/bin/uv pip install --require-hashes -r /opt/mealie/dist/requirements.txt --find-links dist -msg_ok "Installed Mealie" - -msg_info "Downloading NLTK Data" -mkdir -p /nltk_data/ -$STD /opt/mealie/.venv/bin/python -m nltk.downloader -d /nltk_data averaged_perceptron_tagger_eng -msg_ok "Downloaded NLTK Data" - -msg_info "Set Symbolic Links for Mealie" -ln -sf /opt/mealie/.venv/bin/mealie /usr/local/bin/mealie -ln -sf /opt/mealie/.venv/bin/poetry /usr/local/bin/poetry -msg_ok "Set Symbolic Links" - -msg_info "Creating Systemd Service" -cat </etc/systemd/system/mealie.service -[Unit] -Description=Mealie Backend Server -After=network.target postgresql.service - -[Service] -User=root -WorkingDirectory=/opt/mealie -ExecStart=/opt/mealie/start.sh -Restart=always - -[Install] -WantedBy=multi-user.target -EOF -systemctl enable -q --now mealie -msg_ok "Created Service" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" From 2baaf8d187f549f0ea213a2ae586d86054f43db2 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 14 Jul 2025 09:48:42 +0000 Subject: [PATCH 313/463] Update .app files (#713) Co-authored-by: GitHub Actions --- ct/headers/mealie | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 ct/headers/mealie diff --git a/ct/headers/mealie b/ct/headers/mealie deleted file mode 100644 index a5d36d54..00000000 --- a/ct/headers/mealie +++ /dev/null @@ -1,6 +0,0 @@ - __ ___ ___ - / |/ /__ ____ _/ (_)__ - / /|_/ / _ \/ __ `/ / / _ \ - / / / / __/ /_/ / / / __/ -/_/ /_/\___/\__,_/_/_/\___/ - From d649f14a49577c1317db24ce6a1afc1014ba1b5b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 11:52:33 +0200 Subject: [PATCH 314/463] fixes --- misc/tools.func | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 8326d49e..5d226c76 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1894,14 +1894,11 @@ function setup_clickhouse() { if ! command -v clickhouse >/dev/null; then msg_info "Setup ClickHouse" - # → Teste Erreichbarkeit - if ! curl -fsSL --connect-timeout 5 https://packages.clickhouse.com/ping >/dev/null 2>&1; then + if ! curl -fsSL --connect-timeout 5 https://packages.clickhouse.com >/dev/null 2>&1; then msg_error "Connection to packages.clickhouse.com:443 failed – possibly blocked" echo "💡 Check AdGuard/Pi-hole or firewall rules" return 1 fi - - # → Hole GPG-Key if ! curl -fsSL --retry 3 --connect-timeout 10 "$GPG_URL" | gpg --dearmor -o "$GPG_KEY_PATH"; then msg_error "Failed to fetch ClickHouse GPG key" @@ -1911,9 +1908,6 @@ function setup_clickhouse() { echo "deb [signed-by=$GPG_KEY_PATH arch=$ARCH] https://packages.clickhouse.com/deb stable main" \ >/etc/apt/sources.list.d/clickhouse.list - # ────────────────────────────────────────────────────── - # hier unterdrückst du CLICKHOUSE_USER im Env, damit - # die Paket-Skripte nicht den Systemuser 'rybbit' anlegen: env -u CLICKHOUSE_USER $STD apt-get update env -u CLICKHOUSE_USER $STD apt-get install -y \ clickhouse-server clickhouse-client From 1587eea30d2f2fade30f4aaafca47273ad7e21ef Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 11:52:56 +0200 Subject: [PATCH 315/463] Update tools.func --- misc/tools.func | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 5d226c76..ff8eef0f 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1911,22 +1911,18 @@ function setup_clickhouse() { env -u CLICKHOUSE_USER $STD apt-get update env -u CLICKHOUSE_USER $STD apt-get install -y \ clickhouse-server clickhouse-client - # ────────────────────────────────────────────────────── - # jetzt läuft das Paket mit dem Standard-User 'clickhouse' $STD systemctl enable --now clickhouse-server sleep 3 - # → Erst­­installation der Tabelle und des DB-Users clickhouse client --query "CREATE DATABASE IF NOT EXISTS $CLICKHOUSE_DB" clickhouse client --query \ "CREATE USER IF NOT EXISTS $CLICKHOUSE_USER IDENTIFIED WITH plaintext_password BY '$CLICKHOUSE_PASS'" clickhouse client --query \ "GRANT ALL ON $CLICKHOUSE_DB.* TO $CLICKHOUSE_USER" - + 0 msg_ok "Setup ClickHouse (DB: $CLICKHOUSE_DB, User: $CLICKHOUSE_USER)" - # → sichere Credentials zur Kontrolle { echo "ClickHouse DB: $CLICKHOUSE_DB" echo "ClickHouse User: $CLICKHOUSE_USER" From a6fe7b48ba27e5295bb513e9486a0b0a884a742c Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 12:04:19 +0200 Subject: [PATCH 316/463] Update tools.func --- misc/tools.func | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index ff8eef0f..6973e4c6 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -1899,6 +1899,7 @@ function setup_clickhouse() { echo "💡 Check AdGuard/Pi-hole or firewall rules" return 1 fi + if ! curl -fsSL --retry 3 --connect-timeout 10 "$GPG_URL" | gpg --dearmor -o "$GPG_KEY_PATH"; then msg_error "Failed to fetch ClickHouse GPG key" @@ -1909,18 +1910,31 @@ function setup_clickhouse() { >/etc/apt/sources.list.d/clickhouse.list env -u CLICKHOUSE_USER $STD apt-get update - env -u CLICKHOUSE_USER $STD apt-get install -y \ - clickhouse-server clickhouse-client + env -u CLICKHOUSE_USER DEBIAN_FRONTEND=noninteractive $STD apt-get install -y clickhouse-server clickhouse-client $STD systemctl enable --now clickhouse-server - sleep 3 + msg_info "Waiting for ClickHouse to be ready" + for i in {1..10}; do + if clickhouse client --query "SELECT 1" &>/dev/null; then break; fi + sleep 1 + done + + # User anlegen clickhouse client --query "CREATE DATABASE IF NOT EXISTS $CLICKHOUSE_DB" - clickhouse client --query \ - "CREATE USER IF NOT EXISTS $CLICKHOUSE_USER IDENTIFIED WITH plaintext_password BY '$CLICKHOUSE_PASS'" - clickhouse client --query \ - "GRANT ALL ON $CLICKHOUSE_DB.* TO $CLICKHOUSE_USER" - 0 + clickhouse client --query "CREATE USER IF NOT EXISTS $CLICKHOUSE_USER IDENTIFIED WITH plaintext_password BY '$CLICKHOUSE_PASS'" + clickhouse client --query "GRANT ALL ON $CLICKHOUSE_DB.* TO $CLICKHOUSE_USER" + + # Default-User ggf. deaktivieren + cat </etc/clickhouse-server/users.d/disable-default.xml + + + + + +EOF + systemctl restart clickhouse-server + msg_ok "Setup ClickHouse (DB: $CLICKHOUSE_DB, User: $CLICKHOUSE_USER)" { @@ -1931,8 +1945,7 @@ function setup_clickhouse() { else msg_info "Updating ClickHouse packages" env -u CLICKHOUSE_USER $STD apt-get update - env -u CLICKHOUSE_USER $STD apt-get install -y --only-upgrade \ - clickhouse-server clickhouse-client + env -u CLICKHOUSE_USER $STD apt-get install -y --only-upgrade clickhouse-server clickhouse-client msg_ok "ClickHouse updated" fi } From 31d80358c97b083bee5fbcd08c19627090217357 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 12:45:32 +0200 Subject: [PATCH 317/463] testing --- install/bar-assistant-install.sh | 65 ++++++++++++-------------------- 1 file changed, 25 insertions(+), 40 deletions(-) diff --git a/install/bar-assistant-install.sh b/install/bar-assistant-install.sh index 6f8ffa36..8c62182c 100644 --- a/install/bar-assistant-install.sh +++ b/install/bar-assistant-install.sh @@ -7,7 +7,7 @@ # Source: https://github.com/karlomikus/vue-salt-rim # Source: https://www.meilisearch.com/ -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color verb_ip6 catch_errors @@ -17,39 +17,39 @@ update_os msg_info "Installing Dependencies" $STD apt-get install -y \ - composer \ redis-server \ - npm \ nginx \ lsb-release \ - libvips \ - php-{ffi,opcache,redis,zip,pdo-sqlite,bcmath,pdo,curl,dom,fpm} + libvips +#php-{ffi,opcache,redis,zip,pdo-sqlite,bcmath,pdo,curl,dom,fpm} msg_ok "Installed Dependencies" +PHP_VERSION=8.3 PHP_MODULE="ffi,opcache,redis,zip,pdo-sqlite,bcmath,pdo,curl,dom,fpm" setup_php +setup_composer + +fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary" +fetch_and_deploy_gh_release "bar-assistant" "karlomikus/bar-assistant" "tarball" "latest" "/opt/bar-assistant" +fetch_and_deploy_gh_release "vue-salt-rim" "karlomikus/vue-salt-rim" "tarball" "latest" "/opt/vue-salt-rim" + msg_info "Configuring PHP" PHPVER=$(php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION . "\n";') sed -i.bak -E 's/^\s*;?\s*ffi\.enable\s*=.*/ffi.enable=true/' /etc/php/${PHPVER}/fpm/php.ini $STD systemctl reload php${PHPVER}-fpm msg_info "configured PHP" -msg_info "Installing MeiliSearch" -cd /opt -RELEASE_MEILISEARCH=$(curl -s https://api.github.com/repos/meilisearch/meilisearch/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -curl -fsSL https://github.com/meilisearch/meilisearch/releases/latest/download/meilisearch.deb -o meilisearch.deb -$STD dpkg -i meilisearch.deb +msg_info "Configure MeiliSearch" curl -fsSL https://raw.githubusercontent.com/meilisearch/meilisearch/latest/config.toml -o /etc/meilisearch.toml MASTER_KEY=$(openssl rand -base64 12) sed -i \ - -e 's|^env =.*|env = "production"|' \ - -e "s|^# master_key =.*|master_key = \"$MASTER_KEY\"|" \ - -e 's|^db_path =.*|db_path = "/var/lib/meilisearch/data"|' \ - -e 's|^dump_dir =.*|dump_dir = "/var/lib/meilisearch/dumps"|' \ - -e 's|^snapshot_dir =.*|snapshot_dir = "/var/lib/meilisearch/snapshots"|' \ - -e 's|^# no_analytics = true|no_analytics = true|' \ - -e 's|^http_addr =.*|http_addr = "127.0.0.1:7700"|' \ - /etc/meilisearch.toml -echo "${RELEASE_MEILISEARCH}" >/opt/meilisearch_version.txt -msg_ok "Installed MeiliSearch" + -e 's|^env =.*|env = "production"|' \ + -e "s|^# master_key =.*|master_key = \"$MASTER_KEY\"|" \ + -e 's|^db_path =.*|db_path = "/var/lib/meilisearch/data"|' \ + -e 's|^dump_dir =.*|dump_dir = "/var/lib/meilisearch/dumps"|' \ + -e 's|^snapshot_dir =.*|snapshot_dir = "/var/lib/meilisearch/snapshots"|' \ + -e 's|^# no_analytics = true|no_analytics = true|' \ + -e 's|^http_addr =.*|http_addr = "127.0.0.1:7700"|' \ + /etc/meilisearch.toml +msg_ok "Configured MeiliSearch" msg_info "Creating MeiliSearch service" cat </etc/systemd/system/meilisearch.service @@ -68,22 +68,17 @@ systemctl enable -q --now meilisearch msg_ok "Created Service MeiliSearch" msg_info "Installing Bar Assistant" -RELEASE_BARASSISTANT=$(curl -s https://api.github.com/repos/karlomikus/bar-assistant/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -cd /opt -curl -fsSL "https://github.com/karlomikus/bar-assistant/archive/refs/tags/v${RELEASE_BARASSISTANT}.zip" -o barassistant.zip -unzip -q barassistant.zip -mv /opt/bar-assistant-${RELEASE_BARASSISTANT}/ /opt/bar-assistant cd /opt/bar-assistant cp /opt/bar-assistant/.env.dist /opt/bar-assistant/.env MeiliSearch_API_KEY=$(curl -s -X GET 'http://127.0.0.1:7700/keys' -H "Authorization: Bearer $MASTER_KEY" | grep -o '"key":"[^"]*"' | head -n 1 | sed 's/"key":"//;s/"//') MeiliSearch_API_KEY_UID=$(curl -s -X GET 'http://127.0.0.1:7700/keys' -H "Authorization: Bearer $MASTER_KEY" | grep -o '"uid":"[^"]*"' | head -n 1 | sed 's/"uid":"//;s/"//') LOCAL_IP=$(hostname -I | awk '{print $1}') sed -i -e "s|^APP_URL=|APP_URL=http://${LOCAL_IP}/bar/|" \ - -e "s|^MEILISEARCH_HOST=|MEILISEARCH_HOST=http://127.0.0.1:7700|" \ - -e "s|^MEILISEARCH_KEY=|MEILISEARCH_KEY=${MASTER_KEY}|" \ - -e "s|^MEILISEARCH_API_KEY=|MEILISEARCH_API_KEY=${MeiliSearch_API_KEY}|" \ - -e "s|^MEILISEARCH_API_KEY_UID=|MEILISEARCH_API_KEY_UID=${MeiliSearch_API_KEY_UID}|" \ - /opt/bar-assistant/.env + -e "s|^MEILISEARCH_HOST=|MEILISEARCH_HOST=http://127.0.0.1:7700|" \ + -e "s|^MEILISEARCH_KEY=|MEILISEARCH_KEY=${MASTER_KEY}|" \ + -e "s|^MEILISEARCH_API_KEY=|MEILISEARCH_API_KEY=${MeiliSearch_API_KEY}|" \ + -e "s|^MEILISEARCH_API_KEY_UID=|MEILISEARCH_API_KEY_UID=${MeiliSearch_API_KEY_UID}|" \ + /opt/bar-assistant/.env $STD composer install --no-interaction $STD php artisan key:generate touch storage/bar-assistant/database.ba3.sqlite @@ -96,15 +91,9 @@ $STD php artisan route:cache $STD php artisan event:cache mkdir /opt/bar-assistant/storage/bar-assistant/uploads/temp chown -R www-data:www-data /opt/bar-assistant -echo "${RELEASE_BARASSISTANT}" >/opt/${APPLICATION}_version.txt msg_ok "Installed Bar Assistant" msg_info "Installing Salt Rim" -RELEASE_SALTRIM=$(curl -s https://api.github.com/repos/karlomikus/vue-salt-rim/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -cd /opt -curl -fsSL "https://github.com/karlomikus/vue-salt-rim/archive/refs/tags/v${RELEASE_SALTRIM}.zip" -o saltrim.zip -unzip -q saltrim.zip -mv /opt/vue-salt-rim-${RELEASE_SALTRIM}/ /opt/vue-salt-rim cd /opt/vue-salt-rim cat </opt/vue-salt-rim/public/config.js window.srConfig = {} @@ -113,7 +102,6 @@ window.srConfig.MEILISEARCH_URL = "http://${LOCAL_IP}/search" EOF $STD npm install $STD npm run build -echo "${RELEASE_SALTRIM}" >/opt/vue-salt-rim_version.txt msg_ok "Installed Salt Rim" msg_info "Creating Service" @@ -201,9 +189,6 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf /opt/meilisearch.deb -rm -rf "/opt/barassistant.zip" -rm -rf "/opt/saltrim.zip" $STD apt-get -y autoremove $STD apt-get -y autoclean msg_ok "Cleaned" From 3c624f97b39cf564dad0841b8113981a592bec8e Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 12:52:03 +0200 Subject: [PATCH 318/463] Update rybbit-install.sh --- install/rybbit-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/rybbit-install.sh b/install/rybbit-install.sh index 0c8d8cc7..1c4387c2 100644 --- a/install/rybbit-install.sh +++ b/install/rybbit-install.sh @@ -20,7 +20,7 @@ $STD apt-get install -y \ ca-certificates msg_ok "Installed Dependencies" -CLICKHOUSE_DB="rybbit_db" CLICKHOUSE_USER="rybbit" setup_clickhouse +setup_clickhouse PG_VERSION=17 setup_postgresql NODE_VERSION="20" NODE_MODULE="next" setup_nodejs From 786473ac528785cef590f80eaa2bd41175a9c76a Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 12:59:55 +0200 Subject: [PATCH 319/463] tt --- ct/bar-assistant.sh | 197 +++++++++++++++---------------- install/bar-assistant-install.sh | 2 +- 2 files changed, 94 insertions(+), 105 deletions(-) diff --git a/ct/bar-assistant.sh b/ct/bar-assistant.sh index 68f895de..12d8f7ad 100644 --- a/ct/bar-assistant.sh +++ b/ct/bar-assistant.sh @@ -22,111 +22,100 @@ color catch_errors function update_script() { - header_info - check_container_storage - check_container_resources - if [[ ! -d /opt/bar-assistant ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - RELEASE_MEILISEARCH=$(curl -s https://api.github.com/repos/meilisearch/meilisearch/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - RELEASE_BARASSISTANT=$(curl -s https://api.github.com/repos/karlomikus/bar-assistant/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') - RELEASE_SALTRIM=$(curl -s https://api.github.com/repos/karlomikus/vue-salt-rim/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') - - if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE_BARASSISTANT}" != "$(cat /opt/${APP}_version.txt)" ]]; then - msg_info "Stopping nginx" - systemctl stop nginx - msg_ok "Stopped nginx" - - msg_info "Updating ${APP} to v${RELEASE_BARASSISTANT}" - cd /opt - mv /opt/bar-assistant /opt/bar-assistant-backup - curl -fsSL "https://github.com/karlomikus/bar-assistant/archive/refs/tags/v${RELEASE_BARASSISTANT}.zip" -o barassistant.zip - unzip -q barassistant.zip - mv /opt/bar-assistant-${RELEASE_BARASSISTANT}/ /opt/bar-assistant - cp -r /opt/bar-assistant-backup/.env /opt/bar-assistant/.env - cp -r /opt/bar-assistant-backup/storage/bar-assistant /opt/bar-assistant/storage/bar-assistant - cd /opt/bar-assistant - $STD composer install --no-interaction - $STD php artisan migrate --force - $STD php artisan storage:link - $STD php artisan bar:setup-meilisearch - $STD php artisan scout:sync-index-settings - $STD php artisan config:cache - $STD php artisan route:cache - $STD php artisan event:cache - chown -R www-data:www-data /opt/bar-assistant - echo "${RELEASE_BARASSISTANT}" >/opt/${APP}_version.txt - msg_ok "Updated $APP to v${RELEASE_BARASSISTANT}" - - msg_info "Starting nginx" - systemctl start nginx - msg_ok "Started nginx" - - msg_info "Cleaning up" - rm -rf /opt/barassistant.zip - rm -rf /opt/bar-assistant-backup - msg_ok "Cleaned" - else - msg_ok "No update required. ${APP} is already at v${RELEASE_BARASSISTANT}" - fi - - if [[ ! -f /opt/vue-salt-rim_version.txt ]] || [[ "${RELEASE_SALTRIM}" != "$(cat /opt/vue-salt-rim_version.txt)" ]]; then - msg_info "Stopping nginx" - systemctl stop nginx - msg_ok "Stopped nginx" - - msg_info "Updating Salt Rim to v${RELEASE_SALTRIM}" - cd /opt - mv /opt/vue-salt-rim /opt/vue-salt-rim-backup - curl -fsSL "https://github.com/karlomikus/vue-salt-rim/archive/refs/tags/v${RELEASE_SALTRIM}.zip" -o saltrim.zip - unzip -q saltrim.zip - mv /opt/vue-salt-rim-${RELEASE_SALTRIM}/ /opt/vue-salt-rim - cp /opt/vue-salt-rim-backup/public/config.js /opt/vue-salt-rim/public/config.js - cd /opt/vue-salt-rim - $STD npm install - $STD npm run build - echo "${RELEASE_SALTRIM}" >/opt/vue-salt-rim_version.txt - msg_ok "Updated $APP to v${RELEASE_SALTRIM}" - - msg_info "Starting nginx" - systemctl start nginx - msg_ok "Started nginx" - - msg_info "Cleaning up" - rm -rf /opt/saltrim.zip - rm -rf /opt/vue-salt-rim-backup - msg_ok "Cleaned" - msg_ok "Updated" - else - msg_ok "No update required. Salt Rim is already at v${RELEASE_SALTRIM}" - fi - - if [[ ! -f /opt/meilisearch_version.txt ]] || [[ "${RELEASE_MEILISEARCH}" != "$(cat /opt/meilisearch_version.txt)" ]]; then - msg_info "Stopping Meilisearch" - systemctl stop meilisearch - msg_ok "Stopped Meilisearch" - - msg_info "Updating Meilisearch to ${RELEASE_MEILISEARCH}" - cd /opt - RELEASE=$(curl -s https://api.github.com/repos/meilisearch/meilisearch/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - curl -fsSL https://github.com/meilisearch/meilisearch/releases/latest/download/meilisearch.deb -o meilisearch.deb - $STD dpkg -i meilisearch.deb - echo "${RELEASE_MEILISEARCH}" >/opt/meilisearch_version.txt - msg_ok "Updated Meilisearch to ${RELEASE_MEILISEARCH}" - - msg_info "Starting Meilisearch" - systemctl start meilisearch - msg_ok "Started Meilisearch" - - msg_info "Cleaning up" - rm -rf "/opt/meilisearch.deb" - msg_ok "Cleaned" - msg_ok "Updated Meilisearch" - else - msg_ok "No update required. Meilisearch is already at ${RELEASE_MEILISEARCH}" - fi + header_info + check_container_storage + check_container_resources + if [[ ! -d /opt/bar-assistant ]]; then + msg_error "No ${APP} Installation Found!" exit + fi + RELEASE_MEILISEARCH=$(curl -s https://api.github.com/repos/meilisearch/meilisearch/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + RELEASE_BARASSISTANT=$(curl -s https://api.github.com/repos/karlomikus/bar-assistant/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') + RELEASE_SALTRIM=$(curl -s https://api.github.com/repos/karlomikus/vue-salt-rim/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') + + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE_BARASSISTANT}" != "$(cat /opt/${APP}_version.txt)" ]]; then + msg_info "Stopping nginx" + systemctl stop nginx + msg_ok "Stopped nginx" + + msg_info "Backing up Bar Assistant" + mv /opt/bar-assistant /opt/bar-assistant-backup + msg_ok "Backed up Bar Assistant" + + fetch_and_deploy_gh_release "bar-assistant" "karlomikus/bar-assistant" "tarball" "latest" "/opt/bar-assistant" + + msg_info "Updating ${APP} to v${RELEASE_BARASSISTANT}" + cp -r /opt/bar-assistant-backup/.env /opt/bar-assistant/.env + cp -r /opt/bar-assistant-backup/storage/bar-assistant /opt/bar-assistant/storage/bar-assistant + cd /opt/bar-assistant + $STD composer install --no-interaction + $STD php artisan migrate --force + $STD php artisan storage:link + $STD php artisan bar:setup-meilisearch + $STD php artisan scout:sync-index-settings + $STD php artisan config:cache + $STD php artisan route:cache + $STD php artisan event:cache + chown -R www-data:www-data /opt/bar-assistant + msg_ok "Updated $APP to v${RELEASE_BARASSISTANT}" + + msg_info "Starting nginx" + systemctl start nginx + msg_ok "Started nginx" + + msg_info "Cleaning up" + rm -rf /opt/bar-assistant-backup + msg_ok "Cleaned" + else + msg_ok "No update required. ${APP} is already at v${RELEASE_BARASSISTANT}" + fi + + if [[ ! -f /opt/vue-salt-rim_version.txt ]] || [[ "${RELEASE_SALTRIM}" != "$(cat /opt/vue-salt-rim_version.txt)" ]]; then + msg_info "Backing up Vue Salt Rim" + mv /opt/vue-salt-rim /opt/vue-salt-rim-backup + msg_ok "Backed up Vue Salt Rim" + + msg_info "Stopping nginx" + systemctl stop nginx + msg_ok "Stopped nginx" + + fetch_and_deploy_gh_release "vue-salt-rim" "karlomikus/vue-salt-rim" "tarball" "latest" "/opt/vue-salt-rim" + + msg_info "Updating Salt Rim to v${RELEASE_SALTRIM}" + cp /opt/vue-salt-rim-backup/public/config.js /opt/vue-salt-rim/public/config.js + cd /opt/vue-salt-rim + $STD npm install + $STD npm run build + msg_ok "Updated $APP to v${RELEASE_SALTRIM}" + + msg_info "Starting nginx" + systemctl start nginx + msg_ok "Started nginx" + + msg_info "Cleaning up" + rm -rf /opt/vue-salt-rim-backup + msg_ok "Cleaned" + msg_ok "Updated" + else + msg_ok "No update required. Salt Rim is already at v${RELEASE_SALTRIM}" + fi + + if [[ ! -f /opt/meilisearch_version.txt ]] || [[ "${RELEASE_MEILISEARCH}" != "$(cat /opt/meilisearch_version.txt)" ]]; then + msg_info "Stopping Meilisearch" + systemctl stop meilisearch + msg_ok "Stopped Meilisearch" + + fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary" + + msg_info "Starting Meilisearch" + systemctl start meilisearch + msg_ok "Started Meilisearch" + + msg_ok "Updated Meilisearch" + else + msg_ok "No update required. Meilisearch is already at ${RELEASE_MEILISEARCH}" + fi + exit } start diff --git a/install/bar-assistant-install.sh b/install/bar-assistant-install.sh index 8c62182c..febeea89 100644 --- a/install/bar-assistant-install.sh +++ b/install/bar-assistant-install.sh @@ -24,7 +24,7 @@ $STD apt-get install -y \ #php-{ffi,opcache,redis,zip,pdo-sqlite,bcmath,pdo,curl,dom,fpm} msg_ok "Installed Dependencies" -PHP_VERSION=8.3 PHP_MODULE="ffi,opcache,redis,zip,pdo-sqlite,bcmath,pdo,curl,dom,fpm" setup_php +PHP_VERSION="8.3" PHP_FPM=YES PHP_MODULE="ffi,opcache,redis,zip,pdo-sqlite,bcmath,pdo,curl,dom,fpm" setup_php setup_composer fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary" From de149aaa5790ce5a53413d7c9b2c169347102763 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 13:13:28 +0200 Subject: [PATCH 320/463] Update bar-assistant.sh --- ct/bar-assistant.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/bar-assistant.sh b/ct/bar-assistant.sh index 12d8f7ad..29d47eb6 100644 --- a/ct/bar-assistant.sh +++ b/ct/bar-assistant.sh @@ -13,7 +13,7 @@ var_cpu="${var_cpu:-2}" var_ram="${var_ram:-2048}" var_disk="${var_disk:-4}" var_os="${var_os:-ubuntu}" -var_version="${var_version:-24.10}" +var_version="${var_version:-24.04}" var_unprivileged="${var_unprivileged:-1}" header_info "$APP" From 58efa1f41ad489d54cf24c600cbc79459e8f8f50 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 13:22:24 +0200 Subject: [PATCH 321/463] Update bar-assistant.sh --- ct/bar-assistant.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/bar-assistant.sh b/ct/bar-assistant.sh index 29d47eb6..7fd136c7 100644 --- a/ct/bar-assistant.sh +++ b/ct/bar-assistant.sh @@ -12,8 +12,8 @@ var_tags="${var_tags:-inventory;drinks}" var_cpu="${var_cpu:-2}" var_ram="${var_ram:-2048}" var_disk="${var_disk:-4}" -var_os="${var_os:-ubuntu}" -var_version="${var_version:-24.04}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" var_unprivileged="${var_unprivileged:-1}" header_info "$APP" From 614230aede13fad6e309e95e22cea157d74b6b21 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 14:04:58 +0200 Subject: [PATCH 322/463] Update bar-assistant-install.sh --- install/bar-assistant-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/bar-assistant-install.sh b/install/bar-assistant-install.sh index febeea89..4ce66811 100644 --- a/install/bar-assistant-install.sh +++ b/install/bar-assistant-install.sh @@ -65,6 +65,7 @@ Restart=always WantedBy=multi-user.target EOF systemctl enable -q --now meilisearch +sleep 5 msg_ok "Created Service MeiliSearch" msg_info "Installing Bar Assistant" From 4e08c118834ed7cc5d7026b21338b0ff5393553b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 14:13:37 +0200 Subject: [PATCH 323/463] fixes --- install/bar-assistant-install.sh | 2 +- install/rybbit-install.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/install/bar-assistant-install.sh b/install/bar-assistant-install.sh index 4ce66811..00da7c86 100644 --- a/install/bar-assistant-install.sh +++ b/install/bar-assistant-install.sh @@ -26,7 +26,7 @@ msg_ok "Installed Dependencies" PHP_VERSION="8.3" PHP_FPM=YES PHP_MODULE="ffi,opcache,redis,zip,pdo-sqlite,bcmath,pdo,curl,dom,fpm" setup_php setup_composer - +NODE_VERSION="22" setup_nodejs fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary" fetch_and_deploy_gh_release "bar-assistant" "karlomikus/bar-assistant" "tarball" "latest" "/opt/bar-assistant" fetch_and_deploy_gh_release "vue-salt-rim" "karlomikus/vue-salt-rim" "tarball" "latest" "/opt/vue-salt-rim" diff --git a/install/rybbit-install.sh b/install/rybbit-install.sh index 1c4387c2..56f82bcd 100644 --- a/install/rybbit-install.sh +++ b/install/rybbit-install.sh @@ -20,6 +20,7 @@ $STD apt-get install -y \ ca-certificates msg_ok "Installed Dependencies" + setup_clickhouse PG_VERSION=17 setup_postgresql NODE_VERSION="20" NODE_MODULE="next" setup_nodejs From 8f4be68b9f385bafc93bed8dbbaa948a5a6b9727 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 14:33:43 +0200 Subject: [PATCH 324/463] Update bar-assistant.sh --- ct/bar-assistant.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/bar-assistant.sh b/ct/bar-assistant.sh index 7fd136c7..58e4e50c 100644 --- a/ct/bar-assistant.sh +++ b/ct/bar-assistant.sh @@ -29,9 +29,9 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi - RELEASE_MEILISEARCH=$(curl -s https://api.github.com/repos/meilisearch/meilisearch/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - RELEASE_BARASSISTANT=$(curl -s https://api.github.com/repos/karlomikus/bar-assistant/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') - RELEASE_SALTRIM=$(curl -s https://api.github.com/repos/karlomikus/vue-salt-rim/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') + RELEASE_MEILISEARCH=$(curl -fsSL https://api.github.com/repos/meilisearch/meilisearch/releases/latest | jq -r '.tag_name') + RELEASE_BARASSISTANT=$(curl -fsSL https://api.github.com/repos/karlomikus/bar-assistant/releases/latest | jq -r '.tag_name') + RELEASE_SALTRIM=$(curl -fsSL https://api.github.com/repos/karlomikus/vue-salt-rim/releases/latest | jq -r '.tag_name') if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE_BARASSISTANT}" != "$(cat /opt/${APP}_version.txt)" ]]; then msg_info "Stopping nginx" From 6f2e2d067e2effe65516a7c9d1063876b0fb9e07 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 14:40:10 +0200 Subject: [PATCH 325/463] Update bar-assistant.sh --- ct/bar-assistant.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ct/bar-assistant.sh b/ct/bar-assistant.sh index 58e4e50c..6d66dbd9 100644 --- a/ct/bar-assistant.sh +++ b/ct/bar-assistant.sh @@ -33,7 +33,7 @@ function update_script() { RELEASE_BARASSISTANT=$(curl -fsSL https://api.github.com/repos/karlomikus/bar-assistant/releases/latest | jq -r '.tag_name') RELEASE_SALTRIM=$(curl -fsSL https://api.github.com/repos/karlomikus/vue-salt-rim/releases/latest | jq -r '.tag_name') - if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE_BARASSISTANT}" != "$(cat /opt/${APP}_version.txt)" ]]; then + if [[ "${RELEASE_BARASSISTANT}" != "$(cat ~/.bar-assistant 2>/dev/null)" ]] || [[ ! -f ~/.bar-assistant ]]; then msg_info "Stopping nginx" systemctl stop nginx msg_ok "Stopped nginx" @@ -44,7 +44,7 @@ function update_script() { fetch_and_deploy_gh_release "bar-assistant" "karlomikus/bar-assistant" "tarball" "latest" "/opt/bar-assistant" - msg_info "Updating ${APP} to v${RELEASE_BARASSISTANT}" + msg_info "Updating ${APP} to ${RELEASE_BARASSISTANT}" cp -r /opt/bar-assistant-backup/.env /opt/bar-assistant/.env cp -r /opt/bar-assistant-backup/storage/bar-assistant /opt/bar-assistant/storage/bar-assistant cd /opt/bar-assistant @@ -57,7 +57,7 @@ function update_script() { $STD php artisan route:cache $STD php artisan event:cache chown -R www-data:www-data /opt/bar-assistant - msg_ok "Updated $APP to v${RELEASE_BARASSISTANT}" + msg_ok "Updated $APP to ${RELEASE_BARASSISTANT}" msg_info "Starting nginx" systemctl start nginx @@ -67,10 +67,10 @@ function update_script() { rm -rf /opt/bar-assistant-backup msg_ok "Cleaned" else - msg_ok "No update required. ${APP} is already at v${RELEASE_BARASSISTANT}" + msg_ok "No update required. ${APP} is already at ${RELEASE_BARASSISTANT}" fi - if [[ ! -f /opt/vue-salt-rim_version.txt ]] || [[ "${RELEASE_SALTRIM}" != "$(cat /opt/vue-salt-rim_version.txt)" ]]; then + if [[ "${RELEASE_SALTRIM}" != "$(cat ~/.vue-salt-rim 2>/dev/null)" ]] || [[ ! -f ~/.vue-salt-rim ]]; then msg_info "Backing up Vue Salt Rim" mv /opt/vue-salt-rim /opt/vue-salt-rim-backup msg_ok "Backed up Vue Salt Rim" @@ -81,12 +81,12 @@ function update_script() { fetch_and_deploy_gh_release "vue-salt-rim" "karlomikus/vue-salt-rim" "tarball" "latest" "/opt/vue-salt-rim" - msg_info "Updating Salt Rim to v${RELEASE_SALTRIM}" + msg_info "Updating Salt Rim to ${RELEASE_SALTRIM}" cp /opt/vue-salt-rim-backup/public/config.js /opt/vue-salt-rim/public/config.js cd /opt/vue-salt-rim $STD npm install $STD npm run build - msg_ok "Updated $APP to v${RELEASE_SALTRIM}" + msg_ok "Updated $APP to ${RELEASE_SALTRIM}" msg_info "Starting nginx" systemctl start nginx @@ -97,10 +97,10 @@ function update_script() { msg_ok "Cleaned" msg_ok "Updated" else - msg_ok "No update required. Salt Rim is already at v${RELEASE_SALTRIM}" + msg_ok "No update required. Salt Rim is already at ${RELEASE_SALTRIM}" fi - if [[ ! -f /opt/meilisearch_version.txt ]] || [[ "${RELEASE_MEILISEARCH}" != "$(cat /opt/meilisearch_version.txt)" ]]; then + if [[ "${RELEASE_MEILISEARCH}" != "$(cat ~/.meilisearch 2>/dev/null)" ]] || [[ ! -f ~/.meilisearch ]]; then msg_info "Stopping Meilisearch" systemctl stop meilisearch msg_ok "Stopped Meilisearch" From 6fb27b87b989e1d259cd73e475a47444e4c2e156 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 14 Jul 2025 12:42:04 +0000 Subject: [PATCH 326/463] Update versions.json (#714) Co-authored-by: GitHub Actions[bot] --- frontend/public/json/versions.json | 70 +++++++++++++++--------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/frontend/public/json/versions.json b/frontend/public/json/versions.json index 49d435d9..ccd34e86 100644 --- a/frontend/public/json/versions.json +++ b/frontend/public/json/versions.json @@ -1,4 +1,34 @@ [ + { + "name": "theonedev/onedev", + "version": "v12.0.0", + "date": "2025-07-14T06:19:59Z" + }, + { + "name": "wazuh/wazuh", + "version": "coverity-w28-4.13.0", + "date": "2025-07-08T11:25:24Z" + }, + { + "name": "Luligu/matterbridge", + "version": "3.1.3", + "date": "2025-07-14T07:14:31Z" + }, + { + "name": "morpheus65535/bazarr", + "version": "v1.5.3-beta.9", + "date": "2025-07-14T06:07:20Z" + }, + { + "name": "Jackett/Jackett", + "version": "v0.22.2154", + "date": "2025-07-14T06:00:33Z" + }, + { + "name": "firefly-iii/firefly-iii", + "version": "v6.2.20", + "date": "2025-07-02T04:03:37Z" + }, { "name": "steveiliop56/tinyauth", "version": "v3.6.1", @@ -49,11 +79,6 @@ "version": "v4.39.5", "date": "2025-07-13T06:12:47Z" }, - { - "name": "Jackett/Jackett", - "version": "v0.22.2153", - "date": "2025-07-13T05:55:37Z" - }, { "name": "henrygd/beszel", "version": "v0.11.1", @@ -119,11 +144,6 @@ "version": "26.3.1", "date": "2025-07-09T15:41:43Z" }, - { - "name": "firefly-iii/firefly-iii", - "version": "v6.2.20", - "date": "2025-07-02T04:03:37Z" - }, { "name": "fuma-nama/fumadocs", "version": "fumadocs-openapi@9.1.2", @@ -149,6 +169,11 @@ "version": "1.5.35", "date": "2025-06-22T08:30:10Z" }, + { + "name": "neo4j/neo4j", + "version": "2025.06.2", + "date": "2025-07-11T18:03:51Z" + }, { "name": "n8n-io/n8n", "version": "n8n@1.101.2", @@ -229,11 +254,6 @@ "version": "v1.6.10", "date": "2025-07-10T12:04:30Z" }, - { - "name": "neo4j/neo4j", - "version": "5.26.9", - "date": "2025-07-10T10:04:29Z" - }, { "name": "meilisearch/meilisearch", "version": "prototype-incremental-vector-store-3", @@ -334,11 +354,6 @@ "version": "v1.6.2", "date": "2025-07-08T13:52:33Z" }, - { - "name": "wazuh/wazuh", - "version": "coverity-w28-4.13.0", - "date": "2025-07-08T11:25:24Z" - }, { "name": "docker/compose", "version": "v2.38.2", @@ -374,11 +389,6 @@ "version": "v25.2", "date": "2025-07-04T08:21:42Z" }, - { - "name": "morpheus65535/bazarr", - "version": "v1.5.2", - "date": "2025-05-11T16:40:55Z" - }, { "name": "slskd/slskd", "version": "0.23.1", @@ -394,11 +404,6 @@ "version": "v1.0.0-beta14", "date": "2025-07-06T21:07:07Z" }, - { - "name": "Luligu/matterbridge", - "version": "3.1.2", - "date": "2025-07-06T20:55:23Z" - }, { "name": "bluenviron/mediamtx", "version": "v1.13.0", @@ -434,11 +439,6 @@ "version": "v4.3.0", "date": "2025-07-05T12:14:52Z" }, - { - "name": "theonedev/onedev", - "version": "v11.11.4", - "date": "2025-07-05T09:23:25Z" - }, { "name": "linkwarden/linkwarden", "version": "v2.11.3", From 921a6b03d06388a4fc47c6cdddc8202193c3bb17 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 14:50:20 +0200 Subject: [PATCH 327/463] Update bar-assistant.sh --- ct/bar-assistant.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/bar-assistant.sh b/ct/bar-assistant.sh index 6d66dbd9..f20a2b9f 100644 --- a/ct/bar-assistant.sh +++ b/ct/bar-assistant.sh @@ -33,7 +33,7 @@ function update_script() { RELEASE_BARASSISTANT=$(curl -fsSL https://api.github.com/repos/karlomikus/bar-assistant/releases/latest | jq -r '.tag_name') RELEASE_SALTRIM=$(curl -fsSL https://api.github.com/repos/karlomikus/vue-salt-rim/releases/latest | jq -r '.tag_name') - if [[ "${RELEASE_BARASSISTANT}" != "$(cat ~/.bar-assistant 2>/dev/null)" ]] || [[ ! -f ~/.bar-assistant ]]; then + if [[ "v${RELEASE_BARASSISTANT}" != "$(cat ~/.bar-assistant 2>/dev/null)" ]] || [[ ! -f ~/.bar-assistant ]]; then msg_info "Stopping nginx" systemctl stop nginx msg_ok "Stopped nginx" @@ -70,7 +70,7 @@ function update_script() { msg_ok "No update required. ${APP} is already at ${RELEASE_BARASSISTANT}" fi - if [[ "${RELEASE_SALTRIM}" != "$(cat ~/.vue-salt-rim 2>/dev/null)" ]] || [[ ! -f ~/.vue-salt-rim ]]; then + if [[ "v${RELEASE_SALTRIM}" != "$(cat ~/.vue-salt-rim 2>/dev/null)" ]] || [[ ! -f ~/.vue-salt-rim ]]; then msg_info "Backing up Vue Salt Rim" mv /opt/vue-salt-rim /opt/vue-salt-rim-backup msg_ok "Backed up Vue Salt Rim" From ad3f5c54d88c4e4eaf3fad71ccb9213ac7e47a16 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 14:51:47 +0200 Subject: [PATCH 328/463] Update bar-assistant.sh --- ct/bar-assistant.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/bar-assistant.sh b/ct/bar-assistant.sh index f20a2b9f..537b846b 100644 --- a/ct/bar-assistant.sh +++ b/ct/bar-assistant.sh @@ -100,7 +100,7 @@ function update_script() { msg_ok "No update required. Salt Rim is already at ${RELEASE_SALTRIM}" fi - if [[ "${RELEASE_MEILISEARCH}" != "$(cat ~/.meilisearch 2>/dev/null)" ]] || [[ ! -f ~/.meilisearch ]]; then + if [[ "v${RELEASE_MEILISEARCH}" != "$(cat ~/.meilisearch 2>/dev/null)" ]] || [[ ! -f ~/.meilisearch ]]; then msg_info "Stopping Meilisearch" systemctl stop meilisearch msg_ok "Stopped Meilisearch" From 064c9c84e5484ed885283cb126ef4887e22508e2 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 14:58:36 +0200 Subject: [PATCH 329/463] Update bar-assistant.sh --- ct/bar-assistant.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ct/bar-assistant.sh b/ct/bar-assistant.sh index 537b846b..e3ea1afd 100644 --- a/ct/bar-assistant.sh +++ b/ct/bar-assistant.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) +source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) # Copyright (c) 2021-2025 community-scripts ORG -# Author: bvdberg01 +# Author: bvdberg01 | CanbiZ # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://github.com/karlomikus/bar-assistant # Source: https://github.com/karlomikus/vue-salt-rim @@ -29,11 +29,11 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi - RELEASE_MEILISEARCH=$(curl -fsSL https://api.github.com/repos/meilisearch/meilisearch/releases/latest | jq -r '.tag_name') - RELEASE_BARASSISTANT=$(curl -fsSL https://api.github.com/repos/karlomikus/bar-assistant/releases/latest | jq -r '.tag_name') - RELEASE_SALTRIM=$(curl -fsSL https://api.github.com/repos/karlomikus/vue-salt-rim/releases/latest | jq -r '.tag_name') + RELEASE_MEILISEARCH=$(curl -fsSL https://api.github.com/repos/meilisearch/meilisearch/releases/latest | jq -r '.tag_name | sub("^v"; "")') + RELEASE_BARASSISTANT=$(curl -fsSL https://api.github.com/repos/karlomikus/bar-assistant/releases/latest | jq -r '.tag_name | sub("^v"; "")') + RELEASE_SALTRIM=$(curl -fsSL https://api.github.com/repos/karlomikus/vue-salt-rim/releases/latest | jq -r '.tag_name | sub("^v"; "")') - if [[ "v${RELEASE_BARASSISTANT}" != "$(cat ~/.bar-assistant 2>/dev/null)" ]] || [[ ! -f ~/.bar-assistant ]]; then + if [[ "${RELEASE_BARASSISTANT}" != "$(cat ~/.bar-assistant 2>/dev/null)" ]] || [[ ! -f ~/.bar-assistant ]]; then msg_info "Stopping nginx" systemctl stop nginx msg_ok "Stopped nginx" @@ -70,7 +70,7 @@ function update_script() { msg_ok "No update required. ${APP} is already at ${RELEASE_BARASSISTANT}" fi - if [[ "v${RELEASE_SALTRIM}" != "$(cat ~/.vue-salt-rim 2>/dev/null)" ]] || [[ ! -f ~/.vue-salt-rim ]]; then + if [[ "${RELEASE_SALTRIM}" != "$(cat ~/.vue-salt-rim 2>/dev/null)" ]] || [[ ! -f ~/.vue-salt-rim ]]; then msg_info "Backing up Vue Salt Rim" mv /opt/vue-salt-rim /opt/vue-salt-rim-backup msg_ok "Backed up Vue Salt Rim" @@ -100,7 +100,7 @@ function update_script() { msg_ok "No update required. Salt Rim is already at ${RELEASE_SALTRIM}" fi - if [[ "v${RELEASE_MEILISEARCH}" != "$(cat ~/.meilisearch 2>/dev/null)" ]] || [[ ! -f ~/.meilisearch ]]; then + if [[ "${RELEASE_MEILISEARCH}" != "$(cat ~/.meilisearch 2>/dev/null)" ]] || [[ ! -f ~/.meilisearch ]]; then msg_info "Stopping Meilisearch" systemctl stop meilisearch msg_ok "Stopped Meilisearch" From 63b691d6efc86f7ba0b6d08ebc3b4e78d50b10bc Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 14 Jul 2025 16:03:08 +0200 Subject: [PATCH 330/463] finalize --- ct/bar-assistant.sh | 2 +- frontend/public/json/bar-assistant.json | 66 ++++++++++++------------- install/bar-assistant-install.sh | 2 +- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/ct/bar-assistant.sh b/ct/bar-assistant.sh index e3ea1afd..b565c4ee 100644 --- a/ct/bar-assistant.sh +++ b/ct/bar-assistant.sh @@ -8,7 +8,7 @@ source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxV # Source: https://www.meilisearch.com/ APP="Bar-Assistant" -var_tags="${var_tags:-inventory;drinks}" +var_tags="${var_tags:-cocktails;drinks}" var_cpu="${var_cpu:-2}" var_ram="${var_ram:-2048}" var_disk="${var_disk:-4}" diff --git a/frontend/public/json/bar-assistant.json b/frontend/public/json/bar-assistant.json index 9084595d..6558c3f0 100644 --- a/frontend/public/json/bar-assistant.json +++ b/frontend/public/json/bar-assistant.json @@ -1,35 +1,35 @@ { - "name": "Bar-Assistant", - "slug": "bar-assistant", - "categories": [ - 24 - ], - "date_created": "2025-05-25", - "type": "ct", - "updateable": true, - "privileged": false, - "interface_port": 80, - "documentation": "https://docs.barassistant.app/", - "website": "https://barassistant.app/", - "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/bar-assistant.webp", - "config_path": "/opt/bar-assistant", - "description": "Bar assistant is a all-in-one solution for managing your home bar.", - "install_methods": [ - { - "type": "default", - "script": "ct/bar-assistant.sh", - "resources": { - "cpu": 2, - "ram": 2048, - "hdd": 4, - "os": "ubuntu", - "version": "24.10" - } - } - ], - "default_credentials": { - "username": null, - "password": null - }, - "notes": [] + "name": "Bar-Assistant", + "slug": "bar-assistant", + "categories": [ + 24 + ], + "date_created": "2025-07-14", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 80, + "documentation": "https://docs.barassistant.app/", + "website": "https://barassistant.app/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/bar-assistant.webp", + "config_path": "/opt/bar-assistant", + "description": "Bar Assistant is all-in-one solution for managing your home bar. Compared to other recipe management software that usually tries to be more for general use, Bar Assistant is made specifically for managing cocktail recipes. This means that there are a lot of cocktail-oriented features, like ingredient substitutes, first-class ingredients, ABV calculations, unit switching and more..", + "install_methods": [ + { + "type": "default", + "script": "ct/bar-assistant.sh", + "resources": { + "cpu": 2, + "ram": 2048, + "hdd": 4, + "os": "debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] } diff --git a/install/bar-assistant-install.sh b/install/bar-assistant-install.sh index 00da7c86..69ed2f71 100644 --- a/install/bar-assistant-install.sh +++ b/install/bar-assistant-install.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Copyright (c) 2021-2025 community-scripts ORG -# Author: bvdberg01 +# Author: bvdberg01 | CanbiZ # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://github.com/karlomikus/bar-assistant # Source: https://github.com/karlomikus/vue-salt-rim From 6b454adc0e1eb99c2a761d9934bccc2645e61cc1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 14 Jul 2025 14:39:39 +0000 Subject: [PATCH 331/463] Deleted files for issue: bar-assistant --- ct/bar-assistant.sh | 128 ---------------- frontend/public/json/bar-assistant.json | 35 ----- install/bar-assistant-install.sh | 195 ------------------------ 3 files changed, 358 deletions(-) delete mode 100644 ct/bar-assistant.sh delete mode 100644 frontend/public/json/bar-assistant.json delete mode 100644 install/bar-assistant-install.sh diff --git a/ct/bar-assistant.sh b/ct/bar-assistant.sh deleted file mode 100644 index b565c4ee..00000000 --- a/ct/bar-assistant.sh +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) -# Copyright (c) 2021-2025 community-scripts ORG -# Author: bvdberg01 | CanbiZ -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/karlomikus/bar-assistant -# Source: https://github.com/karlomikus/vue-salt-rim -# Source: https://www.meilisearch.com/ - -APP="Bar-Assistant" -var_tags="${var_tags:-cocktails;drinks}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-2048}" -var_disk="${var_disk:-4}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -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/bar-assistant ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - RELEASE_MEILISEARCH=$(curl -fsSL https://api.github.com/repos/meilisearch/meilisearch/releases/latest | jq -r '.tag_name | sub("^v"; "")') - RELEASE_BARASSISTANT=$(curl -fsSL https://api.github.com/repos/karlomikus/bar-assistant/releases/latest | jq -r '.tag_name | sub("^v"; "")') - RELEASE_SALTRIM=$(curl -fsSL https://api.github.com/repos/karlomikus/vue-salt-rim/releases/latest | jq -r '.tag_name | sub("^v"; "")') - - if [[ "${RELEASE_BARASSISTANT}" != "$(cat ~/.bar-assistant 2>/dev/null)" ]] || [[ ! -f ~/.bar-assistant ]]; then - msg_info "Stopping nginx" - systemctl stop nginx - msg_ok "Stopped nginx" - - msg_info "Backing up Bar Assistant" - mv /opt/bar-assistant /opt/bar-assistant-backup - msg_ok "Backed up Bar Assistant" - - fetch_and_deploy_gh_release "bar-assistant" "karlomikus/bar-assistant" "tarball" "latest" "/opt/bar-assistant" - - msg_info "Updating ${APP} to ${RELEASE_BARASSISTANT}" - cp -r /opt/bar-assistant-backup/.env /opt/bar-assistant/.env - cp -r /opt/bar-assistant-backup/storage/bar-assistant /opt/bar-assistant/storage/bar-assistant - cd /opt/bar-assistant - $STD composer install --no-interaction - $STD php artisan migrate --force - $STD php artisan storage:link - $STD php artisan bar:setup-meilisearch - $STD php artisan scout:sync-index-settings - $STD php artisan config:cache - $STD php artisan route:cache - $STD php artisan event:cache - chown -R www-data:www-data /opt/bar-assistant - msg_ok "Updated $APP to ${RELEASE_BARASSISTANT}" - - msg_info "Starting nginx" - systemctl start nginx - msg_ok "Started nginx" - - msg_info "Cleaning up" - rm -rf /opt/bar-assistant-backup - msg_ok "Cleaned" - else - msg_ok "No update required. ${APP} is already at ${RELEASE_BARASSISTANT}" - fi - - if [[ "${RELEASE_SALTRIM}" != "$(cat ~/.vue-salt-rim 2>/dev/null)" ]] || [[ ! -f ~/.vue-salt-rim ]]; then - msg_info "Backing up Vue Salt Rim" - mv /opt/vue-salt-rim /opt/vue-salt-rim-backup - msg_ok "Backed up Vue Salt Rim" - - msg_info "Stopping nginx" - systemctl stop nginx - msg_ok "Stopped nginx" - - fetch_and_deploy_gh_release "vue-salt-rim" "karlomikus/vue-salt-rim" "tarball" "latest" "/opt/vue-salt-rim" - - msg_info "Updating Salt Rim to ${RELEASE_SALTRIM}" - cp /opt/vue-salt-rim-backup/public/config.js /opt/vue-salt-rim/public/config.js - cd /opt/vue-salt-rim - $STD npm install - $STD npm run build - msg_ok "Updated $APP to ${RELEASE_SALTRIM}" - - msg_info "Starting nginx" - systemctl start nginx - msg_ok "Started nginx" - - msg_info "Cleaning up" - rm -rf /opt/vue-salt-rim-backup - msg_ok "Cleaned" - msg_ok "Updated" - else - msg_ok "No update required. Salt Rim is already at ${RELEASE_SALTRIM}" - fi - - if [[ "${RELEASE_MEILISEARCH}" != "$(cat ~/.meilisearch 2>/dev/null)" ]] || [[ ! -f ~/.meilisearch ]]; then - msg_info "Stopping Meilisearch" - systemctl stop meilisearch - msg_ok "Stopped Meilisearch" - - fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary" - - msg_info "Starting Meilisearch" - systemctl start meilisearch - msg_ok "Started Meilisearch" - - msg_ok "Updated Meilisearch" - else - msg_ok "No update required. Meilisearch is already at ${RELEASE_MEILISEARCH}" - 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}http://${IP}${CL}" diff --git a/frontend/public/json/bar-assistant.json b/frontend/public/json/bar-assistant.json deleted file mode 100644 index 6558c3f0..00000000 --- a/frontend/public/json/bar-assistant.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "Bar-Assistant", - "slug": "bar-assistant", - "categories": [ - 24 - ], - "date_created": "2025-07-14", - "type": "ct", - "updateable": true, - "privileged": false, - "interface_port": 80, - "documentation": "https://docs.barassistant.app/", - "website": "https://barassistant.app/", - "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/bar-assistant.webp", - "config_path": "/opt/bar-assistant", - "description": "Bar Assistant is all-in-one solution for managing your home bar. Compared to other recipe management software that usually tries to be more for general use, Bar Assistant is made specifically for managing cocktail recipes. This means that there are a lot of cocktail-oriented features, like ingredient substitutes, first-class ingredients, ABV calculations, unit switching and more..", - "install_methods": [ - { - "type": "default", - "script": "ct/bar-assistant.sh", - "resources": { - "cpu": 2, - "ram": 2048, - "hdd": 4, - "os": "debian", - "version": "12" - } - } - ], - "default_credentials": { - "username": null, - "password": null - }, - "notes": [] -} diff --git a/install/bar-assistant-install.sh b/install/bar-assistant-install.sh deleted file mode 100644 index 69ed2f71..00000000 --- a/install/bar-assistant-install.sh +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 community-scripts ORG -# Author: bvdberg01 | CanbiZ -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/karlomikus/bar-assistant -# Source: https://github.com/karlomikus/vue-salt-rim -# Source: https://www.meilisearch.com/ - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apt-get install -y \ - redis-server \ - nginx \ - lsb-release \ - libvips -#php-{ffi,opcache,redis,zip,pdo-sqlite,bcmath,pdo,curl,dom,fpm} -msg_ok "Installed Dependencies" - -PHP_VERSION="8.3" PHP_FPM=YES PHP_MODULE="ffi,opcache,redis,zip,pdo-sqlite,bcmath,pdo,curl,dom,fpm" setup_php -setup_composer -NODE_VERSION="22" setup_nodejs -fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary" -fetch_and_deploy_gh_release "bar-assistant" "karlomikus/bar-assistant" "tarball" "latest" "/opt/bar-assistant" -fetch_and_deploy_gh_release "vue-salt-rim" "karlomikus/vue-salt-rim" "tarball" "latest" "/opt/vue-salt-rim" - -msg_info "Configuring PHP" -PHPVER=$(php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION . "\n";') -sed -i.bak -E 's/^\s*;?\s*ffi\.enable\s*=.*/ffi.enable=true/' /etc/php/${PHPVER}/fpm/php.ini -$STD systemctl reload php${PHPVER}-fpm -msg_info "configured PHP" - -msg_info "Configure MeiliSearch" -curl -fsSL https://raw.githubusercontent.com/meilisearch/meilisearch/latest/config.toml -o /etc/meilisearch.toml -MASTER_KEY=$(openssl rand -base64 12) -sed -i \ - -e 's|^env =.*|env = "production"|' \ - -e "s|^# master_key =.*|master_key = \"$MASTER_KEY\"|" \ - -e 's|^db_path =.*|db_path = "/var/lib/meilisearch/data"|' \ - -e 's|^dump_dir =.*|dump_dir = "/var/lib/meilisearch/dumps"|' \ - -e 's|^snapshot_dir =.*|snapshot_dir = "/var/lib/meilisearch/snapshots"|' \ - -e 's|^# no_analytics = true|no_analytics = true|' \ - -e 's|^http_addr =.*|http_addr = "127.0.0.1:7700"|' \ - /etc/meilisearch.toml -msg_ok "Configured MeiliSearch" - -msg_info "Creating MeiliSearch service" -cat </etc/systemd/system/meilisearch.service -[Unit] -Description=Meilisearch -After=network.target - -[Service] -ExecStart=/usr/bin/meilisearch --config-file-path /etc/meilisearch.toml -Restart=always - -[Install] -WantedBy=multi-user.target -EOF -systemctl enable -q --now meilisearch -sleep 5 -msg_ok "Created Service MeiliSearch" - -msg_info "Installing Bar Assistant" -cd /opt/bar-assistant -cp /opt/bar-assistant/.env.dist /opt/bar-assistant/.env -MeiliSearch_API_KEY=$(curl -s -X GET 'http://127.0.0.1:7700/keys' -H "Authorization: Bearer $MASTER_KEY" | grep -o '"key":"[^"]*"' | head -n 1 | sed 's/"key":"//;s/"//') -MeiliSearch_API_KEY_UID=$(curl -s -X GET 'http://127.0.0.1:7700/keys' -H "Authorization: Bearer $MASTER_KEY" | grep -o '"uid":"[^"]*"' | head -n 1 | sed 's/"uid":"//;s/"//') -LOCAL_IP=$(hostname -I | awk '{print $1}') -sed -i -e "s|^APP_URL=|APP_URL=http://${LOCAL_IP}/bar/|" \ - -e "s|^MEILISEARCH_HOST=|MEILISEARCH_HOST=http://127.0.0.1:7700|" \ - -e "s|^MEILISEARCH_KEY=|MEILISEARCH_KEY=${MASTER_KEY}|" \ - -e "s|^MEILISEARCH_API_KEY=|MEILISEARCH_API_KEY=${MeiliSearch_API_KEY}|" \ - -e "s|^MEILISEARCH_API_KEY_UID=|MEILISEARCH_API_KEY_UID=${MeiliSearch_API_KEY_UID}|" \ - /opt/bar-assistant/.env -$STD composer install --no-interaction -$STD php artisan key:generate -touch storage/bar-assistant/database.ba3.sqlite -$STD php artisan migrate --force -$STD php artisan storage:link -$STD php artisan bar:setup-meilisearch -$STD php artisan scout:sync-index-settings -$STD php artisan config:cache -$STD php artisan route:cache -$STD php artisan event:cache -mkdir /opt/bar-assistant/storage/bar-assistant/uploads/temp -chown -R www-data:www-data /opt/bar-assistant -msg_ok "Installed Bar Assistant" - -msg_info "Installing Salt Rim" -cd /opt/vue-salt-rim -cat </opt/vue-salt-rim/public/config.js -window.srConfig = {} -window.srConfig.API_URL = "http://${LOCAL_IP}/bar" -window.srConfig.MEILISEARCH_URL = "http://${LOCAL_IP}/search" -EOF -$STD npm install -$STD npm run build -msg_ok "Installed Salt Rim" - -msg_info "Creating Service" -cat </etc/nginx/sites-available/barassistant.conf -server { - listen 80 default_server; - listen [::]:80 default_server; - server_name _; - - location = /favicon.ico { access_log off; log_not_found off; } - location = /robots.txt { access_log off; log_not_found off; } - - client_max_body_size 100M; - - location /bar/ { - proxy_pass http://127.0.0.1:8080/; - proxy_set_header Host \$host; - proxy_set_header X-Real-IP \$remote_addr; - proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto \$scheme; - } - - location /search/ { - proxy_pass http://127.0.0.1:7700/; - } - - location / { - proxy_pass http://127.0.0.1:8081/; - proxy_set_header Host \$host; - proxy_set_header X-Real-IP \$remote_addr; - proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto \$scheme; - } -} - -server { - listen 127.0.0.1:8080; - server_name example.com; - root /opt/bar-assistant/public; - - add_header X-Frame-Options "SAMEORIGIN"; - add_header X-Content-Type-Options "nosniff"; - - index index.php; - charset utf-8; - - location / { - try_files \$uri \$uri/ /index.php?\$query_string; - } - - location = /favicon.ico { access_log off; log_not_found off; } - location = /robots.txt { access_log off; log_not_found off; } - - error_page 404 /index.php; - - location ~ ^/index\.php(/|$) { - fastcgi_pass unix:/var/run/php/php$PHPVER-fpm.sock; - fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name; - include fastcgi_params; - fastcgi_hide_header X-Powered-By; - } - - location ~ /\.(?!well-known).* { - deny all; - } -} - -server { - listen 127.0.0.1:8081; - server_name _; - root /opt/vue-salt-rim/dist; - - location / { - try_files \$uri \$uri/ /index.html; - } -} -EOF - -ln -s /etc/nginx/sites-available/barassistant.conf /etc/nginx/sites-enabled/ -rm -f /etc/nginx/sites-enabled/default -$STD systemctl reload nginx -msg_ok "Created Service" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" From e6013b5a2ac9a0b19d6d31c543824c3f2ad367d0 Mon Sep 17 00:00:00 2001 From: "Jeton R." Date: Mon, 14 Jul 2025 17:04:29 +0200 Subject: [PATCH 332/463] viseron addition (#699) * viseron addition * author name change * change source * Fix build.func URL in viseron script * Update install/viseron-install.sh Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com> * remvoe manual changes from changelog.md * remove changes to repos.txt * remove headers generated file * remove comments as they are only needed for the wiki * modified json file with notes and removed nonstandard echo as requested --------- Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com> --- CHANGELOG.md | 32 +++---- ct/viseron.sh | 38 ++++++++ frontend/public/json/viseron.json | 46 +++++++++ install/viseron-install.sh | 150 ++++++++++++++++++++++++++++++ 4 files changed, 250 insertions(+), 16 deletions(-) create mode 100644 ct/viseron.sh create mode 100644 frontend/public/json/viseron.json create mode 100644 install/viseron-install.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cddfbd3..0de5171d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ ### 🆕 New Scripts - - odoo ([#4477](https://github.com/community-scripts/ProxmoxVE/pull/4477)) +- odoo ([#4477](https://github.com/community-scripts/ProxmoxVE/pull/4477)) - alpine-transmission ([#4277](https://github.com/community-scripts/ProxmoxVE/pull/4277)) - alpine-tinyauth ([#4264](https://github.com/community-scripts/ProxmoxVE/pull/4264)) - alpine-rclone ([#4265](https://github.com/community-scripts/ProxmoxVE/pull/4265)) @@ -24,7 +24,7 @@ ### 🚀 Updated Scripts - - fix: fetch_release_and_deploy function [@CrazyWolf13](https://github.com/CrazyWolf13) ([#4478](https://github.com/community-scripts/ProxmoxVE/pull/4478)) +- fix: fetch_release_and_deploy function [@CrazyWolf13](https://github.com/CrazyWolf13) ([#4478](https://github.com/community-scripts/ProxmoxVE/pull/4478)) - Website: re-add documenso & some little bugfixes [@MickLesk](https://github.com/MickLesk) ([#4456](https://github.com/community-scripts/ProxmoxVE/pull/4456)) - update some improvements from dev (tools.func) [@MickLesk](https://github.com/MickLesk) ([#4430](https://github.com/community-scripts/ProxmoxVE/pull/4430)) - Alpine: Use onliner for updates [@tremor021](https://github.com/tremor021) ([#4414](https://github.com/community-scripts/ProxmoxVE/pull/4414)) @@ -56,26 +56,26 @@ ### 🧰 Maintenance - - #### 💾 Core +- #### 💾 Core - - fix: improve bridge detection in all network interface configuration files [@filippolauria](https://github.com/filippolauria) ([#4413](https://github.com/community-scripts/ProxmoxVE/pull/4413)) - - Config file Function in build.func [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#4411](https://github.com/community-scripts/ProxmoxVE/pull/4411)) - - fix: detect all bridge types, not just vmbr prefix [@filippolauria](https://github.com/filippolauria) ([#4351](https://github.com/community-scripts/ProxmoxVE/pull/4351)) + - fix: improve bridge detection in all network interface configuration files [@filippolauria](https://github.com/filippolauria) ([#4413](https://github.com/community-scripts/ProxmoxVE/pull/4413)) + - Config file Function in build.func [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#4411](https://github.com/community-scripts/ProxmoxVE/pull/4411)) + - fix: detect all bridge types, not just vmbr prefix [@filippolauria](https://github.com/filippolauria) ([#4351](https://github.com/community-scripts/ProxmoxVE/pull/4351)) - - #### 📂 Github +- #### 📂 Github - - Add Github app for auto PR merge [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#4461](https://github.com/community-scripts/ProxmoxVE/pull/4461)) + - Add Github app for auto PR merge [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#4461](https://github.com/community-scripts/ProxmoxVE/pull/4461)) ### 🌐 Website - - FAQ: Explanation "updatable" [@tremor021](https://github.com/tremor021) ([#4300](https://github.com/community-scripts/ProxmoxVE/pull/4300)) +- FAQ: Explanation "updatable" [@tremor021](https://github.com/tremor021) ([#4300](https://github.com/community-scripts/ProxmoxVE/pull/4300)) - - #### 📝 Script Information +- #### 📝 Script Information - - Jellyfin Media Server: Update configuration path [@tremor021](https://github.com/tremor021) ([#4434](https://github.com/community-scripts/ProxmoxVE/pull/4434)) - - Pingvin Share: Added explanation on how to add/edit environment variables [@tremor021](https://github.com/tremor021) ([#4432](https://github.com/community-scripts/ProxmoxVE/pull/4432)) - - pingvin.json: fix typo [@warmbo](https://github.com/warmbo) ([#4426](https://github.com/community-scripts/ProxmoxVE/pull/4426)) - - Navidrome - Fix config path (use /etc/ instead of /var/lib) [@quake1508](https://github.com/quake1508) ([#4406](https://github.com/community-scripts/ProxmoxVE/pull/4406)) + - Jellyfin Media Server: Update configuration path [@tremor021](https://github.com/tremor021) ([#4434](https://github.com/community-scripts/ProxmoxVE/pull/4434)) + - Pingvin Share: Added explanation on how to add/edit environment variables [@tremor021](https://github.com/tremor021) ([#4432](https://github.com/community-scripts/ProxmoxVE/pull/4432)) + - pingvin.json: fix typo [@warmbo](https://github.com/warmbo) ([#4426](https://github.com/community-scripts/ProxmoxVE/pull/4426)) + - Navidrome - Fix config path (use /etc/ instead of /var/lib) [@quake1508](https://github.com/quake1508) ([#4406](https://github.com/community-scripts/ProxmoxVE/pull/4406)) ## 2025-03-24 @@ -86,6 +86,7 @@ - yt-dlp-webui [@CrazyWolf13](https://github.com/CrazyWolf13) ([#3364](https://github.com/community-scripts/ProxmoxVE/pull/3364)) - Extension/New Script: Redis Alpine Installation [@MickLesk](https://github.com/MickLesk) ([#3367](https://github.com/community-scripts/ProxmoxVE/pull/3367)) - Fluid Calendar [@vhsdream](https://github.com/vhsdream) ([#2869](ht + ### 🚀 Updated Scripts - License url VED to VE [@bvdberg01](https://github.com/bvdberg01) ([#3258](https://github.com/community-scripts/ProxmoxVE/pull/3258)) @@ -125,7 +126,6 @@ - #### ✨ New Features - - [core] install core deps (debian / ubuntu) [@MickLesk](https://github.com/MickLesk) ([#3366](https://github.com/community-scripts/ProxmoxVE/pull/3366)) - #### 💾 Core @@ -145,7 +145,7 @@ - #### 🐞 Bug Fixes - - Better Text for Version Date [@michelroegl-brunner](https:er) ([#3388](https://github.com/community-scripts/ProxmoxVE/pull/3388)) + - Better Text for Version Date [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#3388](https://github.com/community-scripts/ProxmoxVE/pull/3388)) - JSON editor note fix [@bvdberg01](https://github.com/bvdberg01) ([#3260](https://github.com/community-scripts/ProxmoxVE/pull/3260)) - Move cryptpad files to right folders [@bvdberg01](https://github.com/bvdberg01) ([#3242](https://github.com/community-scripts/ProxmoxVE/pull/3242)) diff --git a/ct/viseron.sh b/ct/viseron.sh new file mode 100644 index 00000000..8c12645a --- /dev/null +++ b/ct/viseron.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) + +APP="Viseron" +var_tags="${var_tags:-nvr}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-2048}" +var_disk="${var_disk:-10}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +var_unprivileged="${var_unprivileged:-0}" + +header_info "$APP" + +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + if [[ ! -f /etc/systemd/system/viseron.service ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + msg_error "To update Viseron, create a new container and transfer your configuration." + 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}:8888${CL}" diff --git a/frontend/public/json/viseron.json b/frontend/public/json/viseron.json new file mode 100644 index 00000000..3e611c30 --- /dev/null +++ b/frontend/public/json/viseron.json @@ -0,0 +1,46 @@ +{ + "name": "Viseron", + "slug": "viseron", + "categories": [15], + "date_created": "2025-01-15", + "type": "ct", + "updateable": true, + "privileged": false, + "config_path": "/config/viseron.yaml", + "interface_port": 8888, + "documentation": "https://github.com/roflcoopter/viseron", + "website": "https://github.com/roflcoopter/viseron", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/viseron.svg", + "description": "Viseron is an open-source NVR (Network Video Recorder) with object detection capabilities. It can detect objects in video streams and record events when motion is detected.", + "install_methods": [ + { + "type": "default", + "script": "ct/viseron.sh", + "resources": { + "cpu": 2, + "ram": 2048, + "hdd": 10, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [ + { + "text": "Configuration file: /config/viseron.yaml", + "type": "info" + }, + { + "text": "Logs: /config/logs/viseron.log", + "type": "info" + }, + { + "text": "Recordings: /config/recordings", + "type": "info" + } + ] +} diff --git a/install/viseron-install.sh b/install/viseron-install.sh new file mode 100644 index 00000000..3f04fdf6 --- /dev/null +++ b/install/viseron-install.sh @@ -0,0 +1,150 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: jetonr +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/roflcoopter/viseron + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ +python3 python3-pip python3-venv \ +git curl wget \ +libgl1-mesa-glx libglib2.0-0 \ +libsm6 libxext6 libxrender-dev \ +libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 \ +libgstreamer-plugins-bad1.0-0 gstreamer1.0-plugins-base \ +gstreamer1.0-plugins-good gstreamer1.0-plugins-bad \ +gstreamer1.0-plugins-ugly gstreamer1.0-libav \ +gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa \ +gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 \ +gstreamer1.0-pulseaudio \ +libavcodec-dev libavformat-dev libswscale-dev \ +libv4l-dev libxvidcore-dev libx264-dev \ +libjpeg-dev libpng-dev libtiff-dev \ +libatlas-base-dev gfortran \ +libhdf5-dev libhdf5-serial-dev \ +libhdf5-103 libqtgui4 libqtwebkit4 libqt4-test python3-pyqt5 \ +libgtk-3-dev libcanberra-gtk3-module \ +libgirepository1.0-dev libcairo2-dev pkg-config \ +libcblas-dev libopenblas-dev liblapack-dev \ +libsm6 libxext6 libxrender-dev libxss1 \ +libgconf-2-4 libasound2 +msg_ok "Installed Dependencies" + +msg_info "Setting up Python Environment" +cd /opt +python3 -m venv viseron +source viseron/bin/activate +pip install --upgrade pip setuptools wheel +msg_ok "Python Environment Setup" + +msg_info "Installing Viseron" +RELEASE=$(curl -s https://api.github.com/repos/roflcoopter/viseron/releases/latest | jq -r '.tag_name') +pip install viseron==${RELEASE#v} +msg_ok "Installed Viseron $RELEASE" + +msg_info "Creating Configuration Directory" +mkdir -p /config +mkdir -p /config/recordings +mkdir -p /config/logs +msg_ok "Created Configuration Directory" + +msg_info "Creating Default Configuration" +cat </config/viseron.yaml +# Viseron Configuration +# https://github.com/roflcoopter/viseron + +# Logging +logging: + level: INFO + file: /config/logs/viseron.log + +# Web Interface +web: + host: 0.0.0.0 + port: 8888 + +# Cameras +cameras: + # Example camera configuration + # camera_name: + # host: 192.168.1.100 + # port: 554 + # username: admin + # password: password + # path: /stream + # fps: 5 + # width: 1920 + # height: 1080 + +# Object Detection +object_detection: + type: opencv + confidence: 0.5 + labels: + - person + - car + - truck + - bus + - motorcycle + - bicycle + +# Recording +recording: + enabled: true + path: /config/recordings + max_size: 10GB + max_age: 7d + +# Motion Detection +motion_detection: + enabled: true + threshold: 25 + sensitivity: 0.8 +EOF +msg_ok "Created Default Configuration" + +msg_info "Creating Systemd Service" +cat </etc/systemd/system/viseron.service +[Unit] +Description=Viseron NVR Service +After=network.target + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/viseron +Environment=PATH=/opt/viseron/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +ExecStart=/opt/viseron/bin/viseron --config /config/viseron.yaml +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now viseron +msg_ok "Created Systemd Service" + +msg_info "Setting up Hardware Acceleration" +if [[ "$CTTYPE" == "0" ]]; then + chgrp video /dev/dri + chmod 755 /dev/dri + chmod 660 /dev/dri/* +fi +msg_ok "Hardware Acceleration Configured" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 4ba9dc9ec709bff7b093b7b526e27d23b841c620 Mon Sep 17 00:00:00 2001 From: "app-header-generator[bot]" <194485257+app-header-generator[bot]@users.noreply.github.com> Date: Mon, 14 Jul 2025 15:05:05 +0000 Subject: [PATCH 333/463] Update .app files (#717) Co-authored-by: GitHub Actions --- ct/headers/bar-assistant | 6 ------ ct/headers/viseron | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 ct/headers/bar-assistant create mode 100644 ct/headers/viseron diff --git a/ct/headers/bar-assistant b/ct/headers/bar-assistant deleted file mode 100644 index 714e3854..00000000 --- a/ct/headers/bar-assistant +++ /dev/null @@ -1,6 +0,0 @@ - ____ ___ _ __ __ - / __ )____ ______ / | __________(_)____/ /_____ _____ / /_ - / __ / __ `/ ___/_____/ /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ - / /_/ / /_/ / / /_____/ ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ -/_____/\__,_/_/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ - diff --git a/ct/headers/viseron b/ct/headers/viseron new file mode 100644 index 00000000..8cb594da --- /dev/null +++ b/ct/headers/viseron @@ -0,0 +1,6 @@ + _ ___ +| | / (_)_______ _________ ____ +| | / / / ___/ _ \/ ___/ __ \/ __ \ +| |/ / (__ ) __/ / / /_/ / / / / +|___/_/____/\___/_/ \____/_/ /_/ + From fd1095c6c550cf3a5cfb929a5fbe4843c9983c58 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 09:00:59 +0200 Subject: [PATCH 334/463] Update build.func --- misc/build.func | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/misc/build.func b/misc/build.func index d4f94e84..9f094d38 100644 --- a/misc/build.func +++ b/misc/build.func @@ -985,10 +985,11 @@ install_script() { "4" "Use Config File" \ "5" "Manage Default Storage" \ "6" "Diagnostic Settings" \ - "7" "Exit" --nocancel --default-item "1" 3>&1 1>&2 2>&3) + "7" "Exit" \ + --default-item "1" 3>&1 1>&2 2>&3) if [ $? -ne 0 ]; then - echo -e "${CROSS}${RD} Menu canceled. Exiting.${CL}" + echo -e "${CROSS}${RD}Menu canceled. Exiting.${CL}" exit 0 fi @@ -1049,7 +1050,7 @@ install_script() { fi ;; 7) - echo -e "${CROSS}${RD}Exiting.${CL}" + echo -e "${CROSS}${RD}Script Exiting.${CL}" exit 0 ;; *) From 5b12a136f11513d639e477c29f5f4756e6d7c984 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 09:03:41 +0200 Subject: [PATCH 335/463] Update build.func --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 9f094d38..c3fe21da 100644 --- a/misc/build.func +++ b/misc/build.func @@ -988,7 +988,7 @@ install_script() { "7" "Exit" \ --default-item "1" 3>&1 1>&2 2>&3) - if [ $? -ne 0 ]; then + if [ $? -ne 0 ] || [ -z "$CHOICE" ]; then echo -e "${CROSS}${RD}Menu canceled. Exiting.${CL}" exit 0 fi From 16120db26f1d031c7698df276c9033136b912499 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 09:04:55 +0200 Subject: [PATCH 336/463] Update build.func --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index c3fe21da..b50cd1b5 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1050,7 +1050,7 @@ install_script() { fi ;; 7) - echo -e "${CROSS}${RD}Script Exiting.${CL}" + echo -e "\n${CROSS}${RD}Script terminated. Have a great day!${CL}\n" exit 0 ;; *) From c8e7ad6e54fece82dfc755f39be68235e378ebd1 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 09:08:46 +0200 Subject: [PATCH 337/463] Update build.func --- misc/build.func | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/misc/build.func b/misc/build.func index b50cd1b5..1b39a80f 100644 --- a/misc/build.func +++ b/misc/build.func @@ -977,8 +977,9 @@ install_script() { header_info while true; do - CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SETTINGS" --menu "Choose an option:" \ - 20 60 7 \ + TMP_CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --title "SETTINGS" \ + --menu "Choose an option:" 20 60 7 \ "1" "Default Settings" \ "2" "Default Settings (with verbose)" \ "3" "Advanced Settings" \ @@ -986,13 +987,15 @@ install_script() { "5" "Manage Default Storage" \ "6" "Diagnostic Settings" \ "7" "Exit" \ - --default-item "1" 3>&1 1>&2 2>&3) + --default-item "1" 3>&1 1>&2 2>&3) || true - if [ $? -ne 0 ] || [ -z "$CHOICE" ]; then - echo -e "${CROSS}${RD}Menu canceled. Exiting.${CL}" + if [ -z "$TMP_CHOICE" ]; then + echo -e "\n${CROSS}${RD}Menu canceled (ESC pressed). Exiting script.${CL}\n" exit 0 fi + CHOICE="$TMP_CHOICE" + case $CHOICE in 1) header_info From 530aed8d557a9db394e001a559314a08046a71a5 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 10:44:00 +0200 Subject: [PATCH 338/463] Update build.func --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 1b39a80f..f3a06c7d 100644 --- a/misc/build.func +++ b/misc/build.func @@ -990,7 +990,7 @@ install_script() { --default-item "1" 3>&1 1>&2 2>&3) || true if [ -z "$TMP_CHOICE" ]; then - echo -e "\n${CROSS}${RD}Menu canceled (ESC pressed). Exiting script.${CL}\n" + echo -e "\n${CROSS}${RD}Menu canceled. Exiting script.${CL}\n" exit 0 fi From f41c58325a39e31ba656b1f341c4e27a2a8d2a27 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 11:36:49 +0200 Subject: [PATCH 339/463] Update create_lxc.sh --- misc/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index d74ee9fa..f0dab2e6 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -6,7 +6,7 @@ # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # This sets verbose mode if the global variable is set to "yes" -# if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$VERBOSE" == "yes" ]; then set -x; fi if command -v curl >/dev/null 2>&1; then source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) From 184839f96140c5254a25c55bb83fce05ffbbade5 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 13:08:29 +0200 Subject: [PATCH 340/463] test --- ct/nginxproxymanager.sh | 158 +++++++++++++++++++++++++ install/nginxproxymanager-install.sh | 171 +++++++++++++++++++++++++++ 2 files changed, 329 insertions(+) create mode 100644 ct/nginxproxymanager.sh create mode 100644 install/nginxproxymanager-install.sh diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh new file mode 100644 index 00000000..eb7259de --- /dev/null +++ b/ct/nginxproxymanager.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://nginxproxymanager.com/ + +APP="Nginx Proxy Manager" +var_tags="${var_tags:-proxy}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-1024}" +var_disk="${var_disk:-4}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + if [[ ! -f /lib/systemd/system/npm.service ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + if ! command -v pnpm &>/dev/null; then + msg_info "Installing pnpm" + #export NODE_OPTIONS=--openssl-legacy-provider + $STD npm install -g pnpm@8.15 + msg_ok "Installed pnpm" + fi + RELEASE=$(curl -fsSL https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') + msg_info "Stopping Services" + systemctl stop openresty + systemctl stop npm + msg_ok "Stopped Services" + + msg_info "Cleaning Old Files" + rm -rf /app \ + /var/www/html \ + /etc/nginx \ + /var/log/nginx \ + /var/lib/nginx \ + "$STD" /var/cache/nginx + msg_ok "Cleaned Old Files" + + msg_info "Downloading NPM v${RELEASE}" + curl -fsSL "https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE}" | tar -xz + cd nginx-proxy-manager-"${RELEASE}" + msg_ok "Downloaded NPM v${RELEASE}" + + msg_info "Setting up Enviroment" + ln -sf /usr/bin/python3 /usr/bin/python + ln -sf /usr/bin/certbot /opt/certbot/bin/certbot + ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx + ln -sf /usr/local/openresty/nginx/ /etc/nginx + sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" backend/package.json + sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" frontend/package.json + sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf + NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") + for NGINX_CONF in $NGINX_CONFS; do + sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" + done + mkdir -p /var/www/html /etc/nginx/logs + cp -r docker/rootfs/var/www/html/* /var/www/html/ + cp -r docker/rootfs/etc/nginx/* /etc/nginx/ + cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini + cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager + ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf + rm -f /etc/nginx/conf.d/dev.conf + mkdir -p /tmp/nginx/body \ + /run/nginx \ + /data/nginx \ + /data/custom_ssl \ + /data/logs \ + /data/access \ + /data/nginx/default_host \ + /data/nginx/default_www \ + /data/nginx/proxy_host \ + /data/nginx/redirection_host \ + /data/nginx/stream \ + /data/nginx/dead_host \ + /data/nginx/temp \ + /var/lib/nginx/cache/public \ + /var/lib/nginx/cache/private \ + /var/cache/nginx/proxy_temp + chmod -R 777 /var/cache/nginx + chown root /tmp/nginx + echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf + if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then + $STD openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem + fi + mkdir -p /app/global /app/frontend/images + cp -r backend/* /app + cp -r global/* /app/global + $STD python3 -m pip install --no-cache-dir --break-system-packages certbot-dns-cloudflare + msg_ok "Setup Enviroment" + + msg_info "Building Frontend" + cd ./frontend + $STD pnpm install + $STD pnpm upgrade + $STD pnpm run build + cp -r dist/* /app/frontend + cp -r app-images/* /app/frontend/images + msg_ok "Built Frontend" + + msg_info "Initializing Backend" + $STD rm -rf /app/config/default.json + if [ ! -f /app/config/production.json ]; then + cat <<'EOF' >/app/config/production.json +{ + "database": { + "engine": "knex-native", + "knex": { + "client": "sqlite3", + "connection": { + "filename": "/data/database.sqlite" + } + } + } +} +EOF + fi + cd /app + $STD pnpm install + msg_ok "Initialized Backend" + + msg_info "Starting Services" + sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf + sed -i 's/su npm npm/su root root/g' /etc/logrotate.d/nginx-proxy-manager + sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg + systemctl enable -q --now openresty + systemctl enable -q --now npm + msg_ok "Started Services" + + msg_info "Cleaning up" + rm -rf ~/nginx-proxy-manager-* + msg_ok "Cleaned" + + 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}:81${CL}" diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh new file mode 100644 index 00000000..7624a38e --- /dev/null +++ b/install/nginxproxymanager-install.sh @@ -0,0 +1,171 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://nginxproxymanager.com/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get update +$STD apt-get -y install \ + ca-certificates \ + apache2-utils \ + logrotate \ + build-essential \ + jq \ + git +msg_ok "Installed Dependencies" + +NODE_VERSION="20" NODE_MODULE="yarn" NODE_OPTIONS="--openssl-legacy-provider" setup_nodejs +PYTHON_VERSION="3.12" setup_uv +fetch_and_deploy_gh_release "nginxproxymanager" "NginxProxyManager/nginx-proxy-manager" "tarball" "latest" "/tmp/nginxproxymanager" + +msg_info "Installing Python Dependencies" +$STD apt-get install -y \ + python3 \ + python3-dev \ + python3-venv +msg_ok "Installed Python Dependencies" + +msg_info "Setting up Certbot Environment" +$STD uv venv /opt/certbot --python "$PYTHON_VERSION" +/opt/certbot/bin/uv pip install \ + certbot \ + certbot-dns-cloudflare \ + certbot-dns-multi +msg_ok "Certbot Environment Ready" + +msg_info "Installing Openresty" +VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" +curl -fsSL "https://openresty.org/package/pubkey.gpg" | gpg --dearmor -o /etc/apt/trusted.gpg.d/openresty-archive-keyring.gpg +echo -e "deb http://openresty.org/package/debian $VERSION openresty" >/etc/apt/sources.list.d/openresty.list +$STD apt-get update +$STD apt-get -y install openresty +msg_ok "Installed Openresty" + +msg_info "Setting up Environment" +ln -sf /usr/bin/python3 /usr/bin/python +ln -sf /opt/certbot/bin/certbot /usr/bin/certbot +ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx +ln -sf /usr/local/openresty/nginx/ /etc/nginx +sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf +NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") +for NGINX_CONF in $NGINX_CONFS; do + sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" +done + +mkdir -p /var/www/html /etc/nginx/logs +cd /tmp/nginxproxymanager +cp -r docker/rootfs/var/www/html/* /var/www/html/ +cp -r docker/rootfs/etc/nginx/* /etc/nginx/ +cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini +cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager +ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf +rm -f /etc/nginx/conf.d/dev.conf + +mkdir -p /tmp/nginx/body \ + /run/nginx \ + /data/nginx \ + /data/custom_ssl \ + /data/logs \ + /data/access \ + /data/nginx/default_host \ + /data/nginx/default_www \ + /data/nginx/proxy_host \ + /data/nginx/redirection_host \ + /data/nginx/stream \ + /data/nginx/dead_host \ + /data/nginx/temp \ + /var/lib/nginx/cache/public \ + /var/lib/nginx/cache/private \ + /var/cache/nginx/proxy_temp + +chmod -R 777 /var/cache/nginx +chown root /tmp/nginx + +echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf + +if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then + openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null +fi + +mkdir -p /app/global /app/frontend/images +cd /tmp/nginxproxymanager +cp -r backend/* /app +cp -r global/* /app/global +msg_ok "Set up Environment" + +msg_info "Building Frontend" +cd /tmp/nginxproxymanager/frontend +$STD yarn install --frozen-lockfile +$STD yarn build +cp -r dist/* /app/frontend +cp -r app-images/* /app/frontend/images +msg_ok "Built Frontend" + +msg_info "Initializing Backend" +rm -rf /app/config/default.json +if [ ! -f /app/config/production.json ]; then + cat <<'EOF' >/app/config/production.json +{ + "database": { + "engine": "knex-native", + "knex": { + "client": "sqlite3", + "connection": { + "filename": "/data/database.sqlite" + } + } + } +} +EOF +fi +cd /app +$STD yarn install --production +msg_ok "Initialized Backend" + +msg_info "Creating Service" +cat <<'EOF' >/lib/systemd/system/npm.service +[Unit] +Description=Nginx Proxy Manager +After=network.target +Wants=openresty.service + +[Service] +Type=simple +Environment=NODE_ENV=production +Environment=NODE_OPTIONS=--openssl-legacy-provider +ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge +ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=1024 +WorkingDirectory=/app +Restart=on-failure + +[Install] +WantedBy=multi-user.target +EOF +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Starting Services" +sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf +sed -r -i 's/^([[:space:]]*)su npm npm/\1#su npm npm/g;' /etc/logrotate.d/nginx-proxy-manager +systemctl enable -q --now openresty +systemctl enable -q --now npm +msg_ok "Started Services" + +msg_info "Cleaning up" +rm -rf /tmp/* +systemctl restart openresty +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 5e3a99023cb834cc36bb237702a2d430de7cabe2 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 13:12:11 +0200 Subject: [PATCH 341/463] Update create_lxc.sh --- misc/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index f0dab2e6..d74ee9fa 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -6,7 +6,7 @@ # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # This sets verbose mode if the global variable is set to "yes" -if [ "$VERBOSE" == "yes" ]; then set -x; fi +# if [ "$VERBOSE" == "yes" ]; then set -x; fi if command -v curl >/dev/null 2>&1; then source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) From dc92e23a9eaab8db07c3afa0852cd5ec8b4bad74 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 13:15:23 +0200 Subject: [PATCH 342/463] Update nginxproxymanager-install.sh --- install/nginxproxymanager-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 7624a38e..875e952e 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -36,8 +36,8 @@ $STD apt-get install -y \ msg_ok "Installed Python Dependencies" msg_info "Setting up Certbot Environment" -$STD uv venv /opt/certbot --python "$PYTHON_VERSION" -/opt/certbot/bin/uv pip install \ +$STD uv venv /opt/certbot +/opt/certbot/bin/uv pip install --python \ certbot \ certbot-dns-cloudflare \ certbot-dns-multi From 8dcb8cbcac49bedb5277da27d837d32d62a9750b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 13:19:33 +0200 Subject: [PATCH 343/463] Update nginxproxymanager-install.sh --- install/nginxproxymanager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 875e952e..55ee6d61 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -37,7 +37,7 @@ msg_ok "Installed Python Dependencies" msg_info "Setting up Certbot Environment" $STD uv venv /opt/certbot -/opt/certbot/bin/uv pip install --python \ +$STD uv pip install --python \ certbot \ certbot-dns-cloudflare \ certbot-dns-multi From ef2e68e3868f5b21ec7023241ab0a16e428d112f Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 13:28:34 +0200 Subject: [PATCH 344/463] cloudreve --- ct/cloudreve.sh | 44 ++++++++++++++++++++++++++++ install/cloudreve-install.sh | 43 +++++++++++++++++++++++++++ install/nginxproxymanager-install.sh | 2 +- 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 ct/cloudreve.sh create mode 100644 install/cloudreve-install.sh diff --git a/ct/cloudreve.sh b/ct/cloudreve.sh new file mode 100644 index 00000000..37738513 --- /dev/null +++ b/ct/cloudreve.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) +# Copyright (c) 2021-2025 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://www.debian.org/ + +APP="Cloudreve" +var_tags="${var_tags:-cloud}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-1024}" +var_disk="${var_disk:-10}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +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 /var ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + msg_info "Updating $APP LXC" + $STD apt-get update + $STD apt-get -y upgrade + msg_ok "Updated $APP LXC" + 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}:5212${CL}" diff --git a/install/cloudreve-install.sh b/install/cloudreve-install.sh new file mode 100644 index 00000000..51a7dcb4 --- /dev/null +++ b/install/cloudreve-install.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://hanko.io/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +fetch_and_deploy_gh_release "cloudreve" "cloudreve/cloudreve" "prebuild" "latest" "/opt/cloudreve" "hanko_Linux_x86_64.tar.gz" + +msg_info "Setup Service" +cat </etc/systemd/system/cloudreve.service +[Unit] +Description=Cloudreve Service +After=network.target + +[Service] +Type=simple +ExecStart=/opt/cloudreve/cloudreve +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + +systemctl enable -q --now cloudreve +msg_ok "Service Setup" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 55ee6d61..58141d8a 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -56,7 +56,7 @@ ln -sf /usr/bin/python3 /usr/bin/python ln -sf /opt/certbot/bin/certbot /usr/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx -sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf +sed -i 's+^daemon+#daemon+g' /tmp/nginxproxymanager/docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") for NGINX_CONF in $NGINX_CONFS; do sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" From 72f6731e809e092857cb0190f2adf4f686f00528 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 13:31:04 +0200 Subject: [PATCH 345/463] link --- ct/cloudreve.sh | 6 +++--- install/cloudreve-install.sh | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ct/cloudreve.sh b/ct/cloudreve.sh index 37738513..f64fea7a 100644 --- a/ct/cloudreve.sh +++ b/ct/cloudreve.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) -# Copyright (c) 2021-2025 tteck -# Author: tteck (tteckster) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (CanbiZ) # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE -# Source: https://www.debian.org/ +# Source: https://cloudreve.org/ APP="Cloudreve" var_tags="${var_tags:-cloud}" diff --git a/install/cloudreve-install.sh b/install/cloudreve-install.sh index 51a7dcb4..c06c940b 100644 --- a/install/cloudreve-install.sh +++ b/install/cloudreve-install.sh @@ -3,7 +3,7 @@ # Copyright (c) 2021-2025 community-scripts ORG # Author: MickLesk (CanbiZ) # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE -# Source: https://hanko.io/ +# Source: https://cloudreve.org/ source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color @@ -13,7 +13,7 @@ setting_up_container network_check update_os -fetch_and_deploy_gh_release "cloudreve" "cloudreve/cloudreve" "prebuild" "latest" "/opt/cloudreve" "hanko_Linux_x86_64.tar.gz" +fetch_and_deploy_gh_release "cloudreve" "cloudreve/cloudreve" "prebuild" "latest" "/opt/cloudreve" "*amd64.tar.gz" msg_info "Setup Service" cat </etc/systemd/system/cloudreve.service From f6088fcb2fde6ad97359b3260d53e5a573f30e1f Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 13:35:08 +0200 Subject: [PATCH 346/463] Update cloudreve-install.sh --- install/cloudreve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/cloudreve-install.sh b/install/cloudreve-install.sh index c06c940b..c7ef56fa 100644 --- a/install/cloudreve-install.sh +++ b/install/cloudreve-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -fetch_and_deploy_gh_release "cloudreve" "cloudreve/cloudreve" "prebuild" "latest" "/opt/cloudreve" "*amd64.tar.gz" +fetch_and_deploy_gh_release "cloudreve" "cloudreve/cloudreve" "prebuild" "latest" "/opt/cloudreve" "*linux_amd64.tar.gz" msg_info "Setup Service" cat </etc/systemd/system/cloudreve.service From bd6e0ac90fea7e24eb0d300fbea9a4b7f0649746 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 13:59:22 +0200 Subject: [PATCH 347/463] Update build.func --- misc/build.func | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/misc/build.func b/misc/build.func index f3a06c7d..50664ea8 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1245,7 +1245,6 @@ EOF "Ollama" "FileFlows" "Open WebUI" - "Debian" ) is_vaapi_app=false @@ -1319,6 +1318,26 @@ EOF pct start "$CTID" msg_ok "Started LXC Container" + msg_info "Waiting for network in LXC container" + for i in {1..10}; do + if pct exec "$CTID" -- ping -c1 -W1 deb.debian.org >/dev/null 2>&1; then + msg_ok "Network in LXC is reachable" + break + else + msg_warn "No network yet in LXC (try $i/10) – waiting..." + sleep 3 + fi + if [ $i -eq 10 ]; then + msg_error "No network in LXC after waiting. Setting fallback DNS..." + pct set "$CTID" --nameserver 1.1.1.1 + pct set "$CTID" --nameserver 8.8.8.8 + if ! pct exec "$CTID" -- ping -c1 -W1 deb.debian.org >/dev/null 2>&1; then + msg_error "Still no network/DNS in LXC! Aborting customization." + exit 1 + fi + fi + done + msg_info "Customizing LXC Container" if [ "$var_os" == "alpine" ]; then sleep 3 @@ -1346,7 +1365,10 @@ EOF' msg_warn "Skipping timezone setup – zone '$tz' not found in container" fi - pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" + pct exec "$CTID" -- bash -c "apt-get update && apt-get install -y sudo curl mc gnupg2" || { + msg_error "apt-get base packages installation failed" + exit 1 + } fi msg_ok "Customized LXC Container" From a8b2d21905d24f23ae20eccb62c6345d4b3d341a Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 14:01:46 +0200 Subject: [PATCH 348/463] test --- ct/debian.sh | 2 +- install/debian-install.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/debian.sh b/ct/debian.sh index 87fa7f65..c525e5e2 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -12,7 +12,7 @@ var_ram="${var_ram:-512}" var_disk="${var_disk:-2}" var_os="${var_os:-debian}" var_version="${var_version:-12}" -var_unprivileged="${var_unprivileged:-0}" +var_unprivileged="${var_unprivileged:-1}" var_fuse="${var_fuse:-no}" var_tun="${var_tun:-no}" diff --git a/install/debian-install.sh b/install/debian-install.sh index fcca74fc..e6259184 100644 --- a/install/debian-install.sh +++ b/install/debian-install.sh @@ -17,7 +17,7 @@ msg_info "Installing Dependencies" $STD apt-get install -y gpg msg_ok "Installed Dependencies" -setup_mariadb +#setup_mariadb #FFMPEG_VERSION="n7.1.1" FFMPEG_TYPE="full" setup_ffmpeg From 58fe33a4c6d94583b5376e2a6839296d98cf63e5 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 14:20:49 +0200 Subject: [PATCH 349/463] Update nginxproxymanager-install.sh --- install/nginxproxymanager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 58141d8a..a9220b59 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -24,7 +24,7 @@ $STD apt-get -y install \ git msg_ok "Installed Dependencies" -NODE_VERSION="20" NODE_MODULE="yarn" NODE_OPTIONS="--openssl-legacy-provider" setup_nodejs +NODE_VERSION="16" NODE_MODULE="yarn" NODE_OPTIONS="--openssl-legacy-provider" setup_nodejs PYTHON_VERSION="3.12" setup_uv fetch_and_deploy_gh_release "nginxproxymanager" "NginxProxyManager/nginx-proxy-manager" "tarball" "latest" "/tmp/nginxproxymanager" From 633d15f896f49314193ff3162ebf2b7a8099003c Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 15 Jul 2025 14:20:58 +0200 Subject: [PATCH 350/463] Update nginxproxymanager-install.sh --- install/nginxproxymanager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index a9220b59..9aaf4cc4 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -24,7 +24,7 @@ $STD apt-get -y install \ git msg_ok "Installed Dependencies" -NODE_VERSION="16" NODE_MODULE="yarn" NODE_OPTIONS="--openssl-legacy-provider" setup_nodejs +NODE_VERSION="16" NODE_MODULE="yarn" setup_nodejs PYTHON_VERSION="3.12" setup_uv fetch_and_deploy_gh_release "nginxproxymanager" "NginxProxyManager/nginx-proxy-manager" "tarball" "latest" "/tmp/nginxproxymanager" From 1cb3e4bd96141e6a9f13669ed0ebbc904375d3bd Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 16 Jul 2025 08:37:51 +0200 Subject: [PATCH 351/463] rename salt --- ct/{saltmaster.sh => salt.sh} | 2 +- frontend/public/json/cloudreve.json | 35 +++++++++++++++++++ .../json/{saltmaster.json => salt.json} | 14 ++++---- ...{saltmaster-install.sh => salt-install.sh} | 0 4 files changed, 43 insertions(+), 8 deletions(-) rename ct/{saltmaster.sh => salt.sh} (98%) create mode 100644 frontend/public/json/cloudreve.json rename frontend/public/json/{saltmaster.json => salt.json} (72%) rename install/{saltmaster-install.sh => salt-install.sh} (100%) diff --git a/ct/saltmaster.sh b/ct/salt.sh similarity index 98% rename from ct/saltmaster.sh rename to ct/salt.sh index 9cf36a9a..5efed33c 100644 --- a/ct/saltmaster.sh +++ b/ct/salt.sh @@ -5,7 +5,7 @@ source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/ # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://github.com/saltstack/salt -APP="saltmaster" +APP="Salt" var_tags="${var_tags:-automations}" var_cpu="${var_cpu:-1}" var_ram="${var_ram:-1024}" diff --git a/frontend/public/json/cloudreve.json b/frontend/public/json/cloudreve.json new file mode 100644 index 00000000..ff754a10 --- /dev/null +++ b/frontend/public/json/cloudreve.json @@ -0,0 +1,35 @@ +{ + "name": "LibreNMS", + "slug": "librenms", + "categories": [ + 9 + ], + "date_created": "2025-03-24", + "type": "ct", + "updateable": false, + "privileged": false, + "interface_port": 80, + "documentation": "https://docs.librenms.org/", + "website": "https://librenms.org/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/cloudreve.webp", + "config_path": "/opt/librenms/config.php and /opt/librenms/.env", + "description": "LibreNMS is an open-source, community-driven network monitoring system that provides automatic discovery, alerting, and performance tracking for network devices. It supports a wide range of hardware and integrates with various notification and logging platforms.", + "install_methods": [ + { + "type": "default", + "script": "ct/librenms.sh", + "resources": { + "cpu": 2, + "ram": 2048, + "hdd": 4, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": "admin", + "password": "admin" + }, + "notes": [] +} diff --git a/frontend/public/json/saltmaster.json b/frontend/public/json/salt.json similarity index 72% rename from frontend/public/json/saltmaster.json rename to frontend/public/json/salt.json index b538aae1..4c162aba 100644 --- a/frontend/public/json/saltmaster.json +++ b/frontend/public/json/salt.json @@ -1,6 +1,6 @@ { - "name": "Saltmaster", - "slug": "saltmaster", + "name": "Salt", + "slug": "salt", "categories": [ 1 ], @@ -8,16 +8,16 @@ "type": "ct", "updateable": true, "privileged": false, - "config_path": "/opt/saltmaster/.env", + "config_path": "/opt/salt/.env", "interface_port": 3000, - "documentation": "https://saltmaster.io/", - "website": "https://saltmaster.io/", + "documentation": "https://docs.saltproject.io/salt/install-guide/en/latest/", + "website": "https://saltproject.io/", "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/saltmaster.svg", "description": "Saltmaster is an open-source self-hosted application.", "install_methods": [ { "type": "default", - "script": "ct/saltmaster.sh", + "script": "ct/salt.sh", "resources": { "cpu": 1, "ram": 1024, @@ -32,4 +32,4 @@ "password": null }, "notes": [] -} \ No newline at end of file +} diff --git a/install/saltmaster-install.sh b/install/salt-install.sh similarity index 100% rename from install/saltmaster-install.sh rename to install/salt-install.sh From d918ad3c4bd61d3df67db1da076dfa6b2240c4d0 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 16 Jul 2025 09:09:47 +0200 Subject: [PATCH 352/463] Update salt-install.sh --- install/salt-install.sh | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/install/salt-install.sh b/install/salt-install.sh index 24293933..9f50facd 100644 --- a/install/salt-install.sh +++ b/install/salt-install.sh @@ -18,23 +18,25 @@ $STD apt-get install -y \ jq msg_ok "Installed Dependencies" -msg_info "Setup Salt repo" -mkdir -p /etc/apt/keyrings -curl -fsSL https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public -o /etc/apt/keyrings/salt-archive-keyring.pgp -curl -fsSL https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.sources -o /etc/apt/sources.list.d/salt.sources -$STD apt-get update -msg_ok "Setup Salt repo" +fetch_and_deploy_gh_release "salt" "saltstack/salt" "binary" "latest" "/opt/salt" "salt-master*amd64.deb" -msg_info "Installing Salt Master" -RELEASE=$(curl -fsSL https://api.github.com/repos/saltstack/salt/releases/latest | jq -r .tag_name | sed 's/^v//') -cat </etc/apt/preferences.d/salt-pin-1001 -Package: salt-* -Pin: version ${RELEASE} -Pin-Priority: 1001 -EOF -$STD apt-get install -y salt-master -echo "${RELEASE}" >/opt/${APPLICATION}_version.txt -msg_ok "Installed Salt Master" +# msg_info "Setup Salt repo" +# mkdir -p /etc/apt/keyrings +# curl -fsSL https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public -o /etc/apt/keyrings/salt-archive-keyring.pgp +# curl -fsSL https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.sources -o /etc/apt/sources.list.d/salt.sources +# $STD apt-get update +# msg_ok "Setup Salt repo" + +# msg_info "Installing Salt Master" +# RELEASE=$(curl -fsSL https://api.github.com/repos/saltstack/salt/releases/latest | jq -r .tag_name | sed 's/^v//') +# cat </etc/apt/preferences.d/salt-pin-1001 +# Package: salt-* +# Pin: version ${RELEASE} +# Pin-Priority: 1001 +# EOF +# $STD apt-get install -y salt-master +# echo "${RELEASE}" >/~.salt +# msg_ok "Installed Salt Master" motd_ssh customize From 1573a25f2a736d39720ea74bb90de67ba1051d8a Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 16 Jul 2025 09:16:09 +0200 Subject: [PATCH 353/463] Update salt-install.sh --- install/salt-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/salt-install.sh b/install/salt-install.sh index 9f50facd..1f59939b 100644 --- a/install/salt-install.sh +++ b/install/salt-install.sh @@ -18,7 +18,7 @@ $STD apt-get install -y \ jq msg_ok "Installed Dependencies" -fetch_and_deploy_gh_release "salt" "saltstack/salt" "binary" "latest" "/opt/salt" "salt-master*amd64.deb" +fetch_and_deploy_gh_release "salt" "saltstack/salt" "binary" "latest" "/opt/salt" "salt-master*_amd64.deb" # msg_info "Setup Salt repo" # mkdir -p /etc/apt/keyrings From 6a499a983f18ea79058c3955cf8e4bb9f1cfc14d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 16 Jul 2025 15:45:11 +0200 Subject: [PATCH 354/463] Update update-apps.sh --- tools/pve/update-apps.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pve/update-apps.sh b/tools/pve/update-apps.sh index 0c1a979f..8461196c 100644 --- a/tools/pve/update-apps.sh +++ b/tools/pve/update-apps.sh @@ -4,7 +4,7 @@ # Author: BvdBerg01 | Co-Author: remz1337 # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/refs/heads/main/misc/core.func) function header_info { clear From 154e450a4464447f42e0e9c8f8de8f6adc95cf52 Mon Sep 17 00:00:00 2001 From: vhsdream Date: Wed, 16 Jul 2025 17:20:10 -0400 Subject: [PATCH 355/463] New script: Tududi --- ct/tududi.sh | 71 +++++++++++++++++++++++++++++++ frontend/public/json/tududi.json | 40 +++++++++++++++++ install/tududi-install.sh | 73 ++++++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+) create mode 100644 ct/tududi.sh create mode 100644 frontend/public/json/tududi.json create mode 100644 install/tududi-install.sh diff --git a/ct/tududi.sh b/ct/tududi.sh new file mode 100644 index 00000000..7aa6375a --- /dev/null +++ b/ct/tududi.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: vhsdream +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://tududi.com + +APP="Tududi" +var_tags="${var_tags:-todo-app}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-1024}" +var_disk="${var_disk:-4}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +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/tududi ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + RELEASE=$(curl -fsSL https://api.github.com/repos/chrisvel/tududi/releases/latest | yq '.tag_name' | sed 's/^v//') + if [[ "${RELEASE}" != "$(cat ~/.tududi 2>/dev/null)" ]] || [[ ! -f ~/.tududi ]]; then + msg_info "Stopping Service" + systemctl stop tududi + msg_ok "Stopped Service" + + msg_info "Upadting ${APP}" + cp /opt/"$APP"/backend/.env /opt/"$APP".env + rm -rf /opt/"$APP" + fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" + + cd /opt/"$APP" + $STD npm install + export NODE_ENV=production + $STD npm run frontend:build + cp -r ./dist ./backend/dist + cp -r ./public/locales ./backend/dist/locales + mv /opt/"$APP".env /opt/"$APP"/.env + msg_ok "Updated $APP" + + msg_info "Starting Service" + systemctl start tududi + msg_ok "Started Service" + + msg_ok "Updated Successfully" + else + msg_ok "Already up to date" + fi + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${ADVANCED}${BL}Create your initial user in${CL} ${BGN}/opt/${APP}${CL}${BL} in the LXC:${CL}" +echo -e "${TAB3}${BL}npm run user:create ${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3002${CL}" diff --git a/frontend/public/json/tududi.json b/frontend/public/json/tududi.json new file mode 100644 index 00000000..fb06bb9e --- /dev/null +++ b/frontend/public/json/tududi.json @@ -0,0 +1,40 @@ +{ + "name": "Tududi", + "slug": "tududi", + "categories": [ + 12 + ], + "date_created": "2025-07-07", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 3002, + "documentation": null, + "config_path": "/", + "website": "https://tududi.com/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/notesnook.webp", + "description": "Notesnook is a free (as in speech) & open-source note-taking app focused on user privacy & ease of use. To ensure zero knowledge principles, Notesnook encrypts everything on your device using XChaCha20-Poly1305 & Argon2.", + "install_methods": [ + { + "type": "default", + "script": "ct/tududi.sh", + "resources": { + "cpu": 2, + "ram": 1024, + "hdd": 4, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [ + { + "text": "Create users like this: `cd /opt/tududi` => `npm run user:create `", + "type": "info" + } + ] +} diff --git a/install/tududi-install.sh b/install/tududi-install.sh new file mode 100644 index 00000000..a9268d21 --- /dev/null +++ b/install/tududi-install.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +# Copyright (c) 2025 Community Scripts ORG +# Author: vhsdream +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://tududi.com/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y sqlite3 +msg_ok "Installed Dependencies" + +NODE_VERSION="20" setup_nodejs + +msg_info "Installing Tududi" +fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" +cd /opt/"$APPLICATION" +$STD npm install +export NODE_ENV=production +$STD npm run frontend:build +cp -r ./dist ./backend/dist +cp -r ./public/locales ./backend/dist/locales +msg_ok "Installed Tududi" + +msg_info "Creating config and database" +DB_LOCATION="/opt/tududi-db" +UPLOAD_DIR="/opt/tududi-uploads" +mkdir -p {"$DB_LOCATION","$UPLOAD_DIR"} +SECRET="$(openssl rand -hex 64)" +sed -e 's/^GOOGLE/# &/' \ + -e '/TUDUDI_SESSION/s/^# //' \ + -e '/NODE_ENV/s/^# //' \ + -e "s/your_session_secret_here/$SECRET/" \ + -e 's/development/production/' \ + -e "\$a\DB_FILE=$DB_LOCATION/production.sqlite3" \ + -e "\$a\UPLOAD_LOCATION=$UPLOAD_DIR" \ + /opt/tududi/backend/.env.example >/opt/tududi/backend/.env +export DB_FILE="$DB_LOCATION/production.sqlite3" +$STD npm run db:init +msg_ok "Created config and database" + +msg_info "Creating service" +cat </etc/systemd/system/tududi.service +[Unit] +Description=Tududi Service +After=network.target + +[Service] +Type=simple +WorkingDirectory=/opt/tududi +EnvironmentFile=/opt/tududi/backend/.env +ExecStart=/usr/bin/npm run start + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now tududi +msg_ok "Created service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 4fc97ca1df781cef4f6cc2372ff564ff4505568c Mon Sep 17 00:00:00 2001 From: vhsdream Date: Wed, 16 Jul 2025 17:33:42 -0400 Subject: [PATCH 356/463] Fix icon --- frontend/public/json/tududi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/public/json/tududi.json b/frontend/public/json/tududi.json index fb06bb9e..080f210e 100644 --- a/frontend/public/json/tududi.json +++ b/frontend/public/json/tududi.json @@ -12,7 +12,7 @@ "documentation": null, "config_path": "/", "website": "https://tududi.com/", - "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/notesnook.webp", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/tududi.webp", "description": "Notesnook is a free (as in speech) & open-source note-taking app focused on user privacy & ease of use. To ensure zero knowledge principles, Notesnook encrypts everything on your device using XChaCha20-Poly1305 & Argon2.", "install_methods": [ { From cd36c5f8620fad3ba962eea7291960af4fd3a4ca Mon Sep 17 00:00:00 2001 From: vhsdream Date: Wed, 16 Jul 2025 17:40:54 -0400 Subject: [PATCH 357/463] Fix description; copy favicons --- ct/tududi.sh | 1 + frontend/public/json/tududi.json | 2 +- install/tududi-install.sh | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ct/tududi.sh b/ct/tududi.sh index 7aa6375a..ee134713 100644 --- a/ct/tududi.sh +++ b/ct/tududi.sh @@ -45,6 +45,7 @@ function update_script() { $STD npm run frontend:build cp -r ./dist ./backend/dist cp -r ./public/locales ./backend/dist/locales + cp ./public/favicon.* ./backend/dist mv /opt/"$APP".env /opt/"$APP"/.env msg_ok "Updated $APP" diff --git a/frontend/public/json/tududi.json b/frontend/public/json/tududi.json index 080f210e..e02f7c63 100644 --- a/frontend/public/json/tududi.json +++ b/frontend/public/json/tududi.json @@ -13,7 +13,7 @@ "config_path": "/", "website": "https://tududi.com/", "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/tududi.webp", - "description": "Notesnook is a free (as in speech) & open-source note-taking app focused on user privacy & ease of use. To ensure zero knowledge principles, Notesnook encrypts everything on your device using XChaCha20-Poly1305 & Argon2.", + "description": "Self-hosted task management with functional programming architecture, hierarchical organization, and multi-language support.", "install_methods": [ { "type": "default", diff --git a/install/tududi-install.sh b/install/tududi-install.sh index a9268d21..2b58d6eb 100644 --- a/install/tududi-install.sh +++ b/install/tududi-install.sh @@ -27,6 +27,7 @@ export NODE_ENV=production $STD npm run frontend:build cp -r ./dist ./backend/dist cp -r ./public/locales ./backend/dist/locales +cp ./public/favicon.* ./backend/dist msg_ok "Installed Tududi" msg_info "Creating config and database" From d9818797eeada22542e8893580017a2d0a369ddc Mon Sep 17 00:00:00 2001 From: vhsdream Date: Wed, 16 Jul 2025 17:42:19 -0400 Subject: [PATCH 358/463] Add config path to JSON --- frontend/public/json/tududi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/public/json/tududi.json b/frontend/public/json/tududi.json index e02f7c63..e8da8840 100644 --- a/frontend/public/json/tududi.json +++ b/frontend/public/json/tududi.json @@ -10,7 +10,7 @@ "privileged": false, "interface_port": 3002, "documentation": null, - "config_path": "/", + "config_path": "/opt/tududi/backend/.env", "website": "https://tududi.com/", "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/tududi.webp", "description": "Self-hosted task management with functional programming architecture, hierarchical organization, and multi-language support.", From 442c2b8a67ffb6db57c5699ac4e4e1a65473343a Mon Sep 17 00:00:00 2001 From: vhsdream Date: Wed, 16 Jul 2025 17:49:22 -0400 Subject: [PATCH 359/463] Use explicit path --- install/tududi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/tududi-install.sh b/install/tududi-install.sh index 2b58d6eb..17cd07a0 100644 --- a/install/tududi-install.sh +++ b/install/tududi-install.sh @@ -21,7 +21,7 @@ NODE_VERSION="20" setup_nodejs msg_info "Installing Tududi" fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" -cd /opt/"$APPLICATION" +cd /opt/tududi $STD npm install export NODE_ENV=production $STD npm run frontend:build From be46cc130d77c133969bc1c2710ce942daf29ac5 Mon Sep 17 00:00:00 2001 From: vhsdream Date: Wed, 16 Jul 2025 18:10:35 -0400 Subject: [PATCH 360/463] Alter post-installation text --- ct/tududi.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ct/tududi.sh b/ct/tududi.sh index ee134713..431ea85f 100644 --- a/ct/tududi.sh +++ b/ct/tududi.sh @@ -66,7 +66,6 @@ description msg_ok "Completed Successfully!\n" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" -echo -e "${ADVANCED}${BL}Create your initial user in${CL} ${BGN}/opt/${APP}${CL}${BL} in the LXC:${CL}" -echo -e "${TAB3}${BL}npm run user:create ${CL}" +echo -e "${ADVANCED}${BL}Create your initial user in${CL} ${BGN}/opt/${APP}${CL}${BL} in the LXC:${CL} ${RD}npm run user:create ${CL}" echo -e "${INFO}${YW} Access it using the following URL:${CL}" echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3002${CL}" From c0b1b524913e59a01ef19a4b51ef5f3b1bcdcc21 Mon Sep 17 00:00:00 2001 From: vhsdream Date: Wed, 16 Jul 2025 18:32:27 -0400 Subject: [PATCH 361/463] Increase RAM --- ct/tududi.sh | 2 +- frontend/public/json/tududi.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/tududi.sh b/ct/tududi.sh index 431ea85f..81c538c4 100644 --- a/ct/tududi.sh +++ b/ct/tududi.sh @@ -8,7 +8,7 @@ source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/ APP="Tududi" var_tags="${var_tags:-todo-app}" var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-1024}" +var_ram="${var_ram:-2048}" var_disk="${var_disk:-4}" var_os="${var_os:-debian}" var_version="${var_version:-12}" diff --git a/frontend/public/json/tududi.json b/frontend/public/json/tududi.json index e8da8840..fd884ef5 100644 --- a/frontend/public/json/tududi.json +++ b/frontend/public/json/tududi.json @@ -20,7 +20,7 @@ "script": "ct/tududi.sh", "resources": { "cpu": 2, - "ram": 1024, + "ram": 2048, "hdd": 4, "os": "Debian", "version": "12" From 049fc60585f491929d36141c3d6878bfb47f2658 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 17 Jul 2025 08:43:37 +0200 Subject: [PATCH 362/463] Update auto-update-app-headers.yml --- .github/workflows/auto-update-app-headers.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-update-app-headers.yml b/.github/workflows/auto-update-app-headers.yml index 18941379..39ecb5ca 100644 --- a/.github/workflows/auto-update-app-headers.yml +++ b/.github/workflows/auto-update-app-headers.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@v1 + uses: actions/create-github-app-token@v2 with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} From d5b6b672edb771651fe571313c88c01239a79368 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 17 Jul 2025 08:47:28 +0200 Subject: [PATCH 363/463] Update auto-update-app-headers.yml --- .github/workflows/auto-update-app-headers.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-update-app-headers.yml b/.github/workflows/auto-update-app-headers.yml index 39ecb5ca..339ed4c4 100644 --- a/.github/workflows/auto-update-app-headers.yml +++ b/.github/workflows/auto-update-app-headers.yml @@ -27,7 +27,7 @@ jobs: - name: Generate a token for PR approval and merge id: generate-token-merge - uses: actions/create-github-app-token@v1 + uses: actions/create-github-app-token@v2 with: app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }} private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }} From 64569d5d67e4f20b3b8c1d20be10ecf1840f637d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 17 Jul 2025 14:07:03 +0200 Subject: [PATCH 364/463] fix --- frontend/public/json/cloudreve.json | 6 +++--- install/salt-install.sh | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/frontend/public/json/cloudreve.json b/frontend/public/json/cloudreve.json index ff754a10..798a07cc 100644 --- a/frontend/public/json/cloudreve.json +++ b/frontend/public/json/cloudreve.json @@ -17,7 +17,7 @@ "install_methods": [ { "type": "default", - "script": "ct/librenms.sh", + "script": "ct/cloudreve.sh", "resources": { "cpu": 2, "ram": 2048, @@ -28,8 +28,8 @@ } ], "default_credentials": { - "username": "admin", - "password": "admin" + "username": null, + "password": null }, "notes": [] } diff --git a/install/salt-install.sh b/install/salt-install.sh index 1f59939b..7c74b7c1 100644 --- a/install/salt-install.sh +++ b/install/salt-install.sh @@ -14,8 +14,7 @@ network_check update_os msg_info "Installing Dependencies" -$STD apt-get install -y \ - jq +$STD apt-get install -y jq msg_ok "Installed Dependencies" fetch_and_deploy_gh_release "salt" "saltstack/salt" "binary" "latest" "/opt/salt" "salt-master*_amd64.deb" From 838a73fb90f6e2b33d22029077e05afd2fa544c6 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 17 Jul 2025 14:28:06 +0200 Subject: [PATCH 365/463] fix json --- frontend/public/json/cloudreve.json | 31 +++++++++++++++++------------ 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/frontend/public/json/cloudreve.json b/frontend/public/json/cloudreve.json index 798a07cc..060b2d83 100644 --- a/frontend/public/json/cloudreve.json +++ b/frontend/public/json/cloudreve.json @@ -1,27 +1,27 @@ { - "name": "LibreNMS", - "slug": "librenms", + "name": "Cloudreve", + "slug": "cloudreve", "categories": [ - 9 + 12 ], - "date_created": "2025-03-24", + "date_created": "2025-07-17", "type": "ct", "updateable": false, "privileged": false, - "interface_port": 80, - "documentation": "https://docs.librenms.org/", - "website": "https://librenms.org/", + "interface_port": 5212, + "documentation": "https://docs.cloudreve.org/en/", + "website": "https://cloudreve.org/", "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/cloudreve.webp", - "config_path": "/opt/librenms/config.php and /opt/librenms/.env", - "description": "LibreNMS is an open-source, community-driven network monitoring system that provides automatic discovery, alerting, and performance tracking for network devices. It supports a wide range of hardware and integrates with various notification and logging platforms.", + "config_path": "/opt/cloudreve/data/config.ini", + "description": "Cloudreve is an open-source, community-driven cloud storage system that provides file sharing, synchronization, and management features. It supports a wide range of storage backends and integrates with various notification and logging platforms.", "install_methods": [ { "type": "default", "script": "ct/cloudreve.sh", "resources": { - "cpu": 2, - "ram": 2048, - "hdd": 4, + "cpu": 1, + "ram": 1024, + "hdd": 10, "os": "Debian", "version": "12" } @@ -31,5 +31,10 @@ "username": null, "password": null }, - "notes": [] + "notes": [ + { + "text": "After Installation: Register your user -> Login -> Dashboard -> Accept Primary URL.", + "type": "info" + } + ] } From c61351b8680a1632ebea041459807a507a1f7204 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 17 Jul 2025 14:28:41 +0200 Subject: [PATCH 366/463] Update cloudreve.json --- frontend/public/json/cloudreve.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/public/json/cloudreve.json b/frontend/public/json/cloudreve.json index 060b2d83..61fa2ce0 100644 --- a/frontend/public/json/cloudreve.json +++ b/frontend/public/json/cloudreve.json @@ -34,7 +34,7 @@ "notes": [ { "text": "After Installation: Register your user -> Login -> Dashboard -> Accept Primary URL.", - "type": "info" + "type": "warn" } ] } From a727d30127f59fac12e46b11dfe56e7dfeef1a27 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 17 Jul 2025 14:35:10 +0200 Subject: [PATCH 367/463] Update cloudreve.sh --- ct/cloudreve.sh | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/ct/cloudreve.sh b/ct/cloudreve.sh index f64fea7a..ce5ee296 100644 --- a/ct/cloudreve.sh +++ b/ct/cloudreve.sh @@ -23,14 +23,28 @@ function update_script() { header_info check_container_storage check_container_resources - if [[ ! -d /var ]]; then + + if [[ ! -d /opt/cloudreve ]]; then msg_error "No ${APP} Installation Found!" exit fi - msg_info "Updating $APP LXC" - $STD apt-get update - $STD apt-get -y upgrade - msg_ok "Updated $APP LXC" + + RELEASE=$(curl -fsSL https://api.github.com/repos/cloudreve/cloudreve/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + if [[ "${RELEASE}" != "$(cat ~/.cloudreve 2>/dev/null)" ]] || [[ ! -f ~/.cloudreve ]]; then + msg_info "Stopping $APP" + systemctl stop cloudreve + msg_ok "Stopped $APP" + + fetch_and_deploy_gh_release "cloudreve" "cloudreve/cloudreve" "prebuild" "latest" "/opt/cloudreve" "*linux_amd64.tar.gz" + + msg_info "Starting $APP" + systemctl start cloudreve + msg_ok "Started $APP" + + msg_ok "Update Successful" + else + msg_ok "No update required. ${APP} is already at v${RELEASE}" + fi exit } From e90783865422fecb0c7d184920bbff2d376171a5 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 17 Jul 2025 15:22:02 +0200 Subject: [PATCH 368/463] Update linkstack-install.sh --- install/linkstack-install.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/install/linkstack-install.sh b/install/linkstack-install.sh index 1d6ce833..87e8c14d 100644 --- a/install/linkstack-install.sh +++ b/install/linkstack-install.sh @@ -18,9 +18,7 @@ $STD apt-get install -y \ software-properties-common \ ca-certificates \ lsb-release \ - apt-transport-https \ - apache2 - unzip + apt-transport-https msg_ok "Installed dependencies" PHP_VERSION="8.2" PHP_MODULE="sqlite3, mysql, fileinfo" PHP_APACHE="YES" install_php From e77563e6bc73ed58c24d116566086adb85652f29 Mon Sep 17 00:00:00 2001 From: dadcoachengineer Date: Thu, 17 Jul 2025 11:01:14 -0500 Subject: [PATCH 369/463] Fixed curl command at line 137 for libusb --- install/frigate-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 557fd9d3..daf95b43 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -134,7 +134,7 @@ msg_info "Installing Coral Object Detection Model (Patience)" cd /opt/frigate export CCACHE_DIR=/root/.ccache export CCACHE_MAXSIZE=2G -curl -fsSL https://github.com/libusb/libusb/archive/v1.0.26.zip +curl -L -o v1.0.26.zip https://github.com/libusb/libusb/archive/v1.0.26.zip unzip -q v1.0.26.zip rm v1.0.26.zip cd libusb-1.0.26 From 3ab0eeabb9ab01f1ac1b9e0e5628947ff1952e4b Mon Sep 17 00:00:00 2001 From: vhsdream Date: Thu, 17 Jul 2025 13:08:57 -0400 Subject: [PATCH 370/463] Delete Reactive-Resume --- ct/reactive-resume.sh | 100 ------------ frontend/public/json/reactive-resume.json | 36 ----- install/reactive-resume-install.sh | 178 ---------------------- 3 files changed, 314 deletions(-) delete mode 100644 ct/reactive-resume.sh delete mode 100644 frontend/public/json/reactive-resume.json delete mode 100644 install/reactive-resume-install.sh diff --git a/ct/reactive-resume.sh b/ct/reactive-resume.sh deleted file mode 100644 index 52a2fdce..00000000 --- a/ct/reactive-resume.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2025 community-scripts ORG -# Author: vhsdream -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://rxresume.org - -APP="Reactive-Resume" -var_tags="${var_tags:-documents}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-3072}" -var_disk="${var_disk:-8}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -var_unprivileged="${var_unprivileged:-1}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - header_info - check_container_storage - check_container_resources - - if [[ ! -f /etc/systemd/system/Reactive-Resume.service ]]; then - msg_error "No $APP Installation Found!" - exit - fi - RELEASE=$(curl -fsSL https://api.github.com/repos/lazy-media/Reactive-Resume/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') - if [[ ! -f "$HOME"/.reactive-resume ]] || [[ "$RELEASE" != "$(cat "$HOME"/.reactive-resume)" ]]; then - msg_info "Stopping services" - systemctl stop Reactive-Resume - msg_ok "Stopped services" - - msg_info "Updating $APP to v${RELEASE}" - cp /opt/"$APP"/.env /opt/rxresume.env - fetch_and_deploy_gh_release "Reactive-Resume" "lazy-media/Reactive-Resume" - cd /opt/"$APP" - export PUPPETEER_SKIP_DOWNLOAD="true" - export NEXT_TELEMETRY_DISABLED=1 - export CI="true" - export NODE_ENV="production" - $STD pnpm install --frozen-lockfile - $STD pnpm run build - $STD pnpm run prisma:generate - mv /opt/rxresume.env /opt/"$APP"/.env - msg_ok "Updated $APP to v$RELEASE" - - msg_info "Updating Minio" - systemctl stop minio - cd /tmp - curl -fsSL https://dl.min.io/server/minio/release/linux-amd64/minio.deb -o minio.deb - $STD dpkg -i minio.deb - msg_ok "Updated Minio" - - msg_info "Updating Browserless (Patience)" - systemctl stop browserless - cp /opt/browserless/.env /opt/browserless.env - rm -rf browserless - brwsr_tmp=$(mktemp) - TAG=$(curl -fsSL https://api.github.com/repos/browserless/browserless/tags?per_page=1 | grep "name" | awk '{print substr($2, 3, length($2)-4) }') - curl -fsSL https://github.com/browserless/browserless/archive/refs/tags/v"$TAG".zip -O "$brwsr_tmp" - $STD unzip "$brwsr_tmp" - mv browserless-"$TAG"/ /opt/browserless - cd /opt/browserless - $STD npm install - rm -rf src/routes/{chrome,edge,firefox,webkit} - $STD node_modules/playwright-core/cli.js install --with-deps chromium - $STD npm run build - $STD npm run build:function - $STD npm prune production - mv /opt/browserless.env /opt/browserless/.env - msg_ok "Updated Browserless" - - msg_info "Restarting services" - systemctl start minio Reactive-Resume browserless - msg_ok "Restarted services" - - msg_info "Cleaning Up" - rm -f /tmp/minio.deb - rm -f "$brwsr_tmp" - msg_ok "Cleanup Completed" - - msg_ok "Update Successful" - else - msg_ok "No update required. $APP is already at v$RELEASE" - 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}http://${IP}:3000${CL}" diff --git a/frontend/public/json/reactive-resume.json b/frontend/public/json/reactive-resume.json deleted file mode 100644 index 5c99acfb..00000000 --- a/frontend/public/json/reactive-resume.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "Reactive Resume", - "slug": "reactive-resume", - "categories": [ - 12 - ], - "date_created": "2025-04-22", - "type": "ct", - "updateable": true, - "privileged": false, - "interface_port": 3000, - "documentation": "https://docs.rxresume.org/", - "website": "https://rxresume.org", - "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/png/reactive-resume-light.png", - "config_path": "/opt/reactive-resume/.env", - "description": "A one-of-a-kind resume builder that keeps your privacy in mind. Completely secure, customizable, portable, open-source and free forever.", - "install_methods": [ - { - "type": "default", - "script": "ct/reactive-resume.sh", - "resources": { - "cpu": 2, - "ram": 3072, - "hdd": 8, - "os": "Debian", - "version": "12" - } - } - ], - "default_credentials": { - "username": null, - "password": null - }, - "notes": [] -} - diff --git a/install/reactive-resume-install.sh b/install/reactive-resume-install.sh deleted file mode 100644 index 895ace02..00000000 --- a/install/reactive-resume-install.sh +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 community-scripts ORG -# Author: vhsdream -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://rxresume.org - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -cd /tmp -curl -fsSL https://dl.min.io/server/minio/release/linux-amd64/minio.deb -o minio.deb -$STD dpkg -i minio.deb -msg_ok "Installed Dependencies" - -PG_VERSION="16" PG_MODULES="common" setup_postgresql -NODE_VERSION="22" NODE_MODULE="pnpm@latest" setup_nodejs - -msg_info "Setting up Database" -DB_USER="rxresume" -DB_NAME="rxresume" -DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) -$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH ENCRYPTED PASSWORD '$DB_PASS';" -$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;" -$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME to $DB_USER;" -$STD sudo -u postgres psql -c "ALTER USER $DB_USER WITH SUPERUSER;" -msg_ok "Set up Database" - -msg_info "Installing $APPLICATION" -MINIO_PASS=$(openssl rand -base64 48) -ACCESS_TOKEN=$(openssl rand -base64 48) -REFRESH_TOKEN=$(openssl rand -base64 48) -CHROME_TOKEN=$(openssl rand -hex 32) -LOCAL_IP=$(hostname -I | awk '{print $1}') -TAG=$(curl -fsSL https://api.github.com/repos/browserless/browserless/tags?per_page=1 | grep "name" | awk '{print substr($2, 3, length($2)-4) }') - -fetch_and_deploy_gh_release "Reactive-Resume" "lazy-media/Reactive-Resume" -cd /opt/"$APPLICATION" -# corepack enable -export CI="true" -export PUPPETEER_SKIP_DOWNLOAD="true" -export NODE_ENV="production" -export NEXT_TELEMETRY_DISABLED=1 -$STD pnpm install --frozen-lockfile -$STD pnpm run build -$STD pnpm install --prod --frozen-lockfile -$STD pnpm run prisma:generate -msg_ok "Installed $APPLICATION" - -msg_info "Installing Browserless (Patience)" -cd /tmp -curl -fsSL https://github.com/browserless/browserless/archive/refs/tags/v"$TAG".zip -o v"$TAG".zip -$STD unzip v"$TAG".zip -mv browserless-"$TAG" /opt/browserless -cd /opt/browserless -$STD npm install -rm -rf src/routes/{chrome,edge,firefox,webkit} -$STD node_modules/playwright-core/cli.js install --with-deps chromium -$STD npm run build -$STD npm run build:function -$STD npm prune production -msg_ok "Installed Browserless" - -msg_info "Configuring applications" -mkdir -p /opt/minio -cat </opt/minio/.env -MINIO_ROOT_USER="storageadmin" -MINIO_ROOT_PASSWORD="${MINIO_PASS}" -MINIO_VOLUMES=/opt/minio -MINIO_OPTS="--address :9000 --console-address 127.0.0.1:9001" -EOF -cat </opt/"$APPLICATION"/.env -NODE_ENV=production -PORT=3000 -PUBLIC_URL=http://${LOCAL_IP}:3000 -STORAGE_URL=http://${LOCAL_IP}:9000/rxresume -DATABASE_URL=postgresql://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}?schema=public -ACCESS_TOKEN_SECRET=${ACCESS_TOKEN} -REFRESH_TOKEN_SECRET=${REFRESH_TOKEN} -CHROME_PORT=8080 -CHROME_TOKEN=${CHROME_TOKEN} -CHROME_URL=ws://localhost:8080 -CHROME_IGNORE_HTTPS_ERRORS=true -MAIL_FROM=noreply@locahost -# SMTP_URL=smtp://username:password@smtp.server.mail:587 # -STORAGE_ENDPOINT=localhost -STORAGE_PORT=9000 -STORAGE_REGION=us-east-1 -STORAGE_BUCKET=rxresume -STORAGE_ACCESS_KEY=storageadmin -STORAGE_SECRET_KEY=${MINIO_PASS} -STORAGE_USE_SSL=false -STORAGE_SKIP_BUCKET_CHECK=false - -# GitHub (OAuth, Optional) -# GITHUB_CLIENT_ID= -# GITHUB_CLIENT_SECRET= -# GITHUB_CALLBACK_URL=http://localhost:5173/api/auth/github/callback - -# Google (OAuth, Optional) -# GOOGLE_CLIENT_ID= -# GOOGLE_CLIENT_SECRET= -# GOOGLE_CALLBACK_URL=http://localhost:5173/api/auth/google/callback -EOF -cat </opt/browserless/.env -DEBUG=browserless*,-**:verbose -HOST=localhost -PORT=8080 -TOKEN=${CHROME_TOKEN} -EOF -{ - echo "${APPLICATION} Credentials" - echo "Database User: $DB_USER" - echo "Database Password: $DB_PASS" - echo "Database Name: $DB_NAME" - echo "Minio Root Password: ${MINIO_PASS}" -} >>~/"$APPLICATION".creds -msg_ok "Configured applications" - -msg_info "Creating Services" -mkdir -p /etc/systemd/system/minio.service.d/ -cat </etc/systemd/system/minio.service.d/override.conf -[Service] -User=root -Group=root -WorkingDirectory=/usr/local/bin -EnvironmentFile=/opt/minio/.env -EOF - -cat </etc/systemd/system/"$APPLICATION".service -[Unit] -Description=${APPLICATION} Service -After=network.target postgresql.service minio.service -Wants=postgresql.service minio.service - -[Service] -WorkingDirectory=/opt/${APPLICATION} -EnvironmentFile=/opt/${APPLICATION}/.env -ExecStart=/usr/bin/pnpm run start -Restart=always - -[Install] -WantedBy=multi-user.target -EOF - -cat </etc/systemd/system/browserless.service -[Unit] -Description=Browserless service -After=network.target ${APPLICATION}.service - -[Service] -WorkingDirectory=/opt/browserless -EnvironmentFile=/opt/browserless/.env -ExecStart=/usr/bin/npm run start -Restart=unless-stopped - -[Install] -WantedBy=multi-user.target -EOF -systemctl daemon-reload -systemctl enable -q --now minio.service "$APPLICATION".service browserless.service -msg_ok "Created Services" - -motd_ssh -customize - -msg_info "Cleaning up" -rm -f /tmp/v"$TAG".zip -rm -f /tmp/minio.deb -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" From e0528ba540daf7d51e82606e58887ca9f035d158 Mon Sep 17 00:00:00 2001 From: vhsdream Date: Thu, 17 Jul 2025 16:44:50 -0400 Subject: [PATCH 371/463] typo fix --- ct/tududi.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/tududi.sh b/ct/tududi.sh index 81c538c4..a4d6a4d4 100644 --- a/ct/tududi.sh +++ b/ct/tududi.sh @@ -34,7 +34,7 @@ function update_script() { systemctl stop tududi msg_ok "Stopped Service" - msg_info "Upadting ${APP}" + msg_info "Updating ${APP}" cp /opt/"$APP"/backend/.env /opt/"$APP".env rm -rf /opt/"$APP" fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" From 063bed19c1640c92d627ba2e2245fd19f633bddc Mon Sep 17 00:00:00 2001 From: Bas van den Berg <74251551+bvdberg01@users.noreply.github.com> Date: Sun, 20 Jul 2025 13:23:07 +0200 Subject: [PATCH 372/463] Update ots-install.sh --- install/ots-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/ots-install.sh b/install/ots-install.sh index 437e3010..2c6b5f24 100644 --- a/install/ots-install.sh +++ b/install/ots-install.sh @@ -22,7 +22,7 @@ msg_ok "Installed Dependencies" msg_info "Installing OTS" fetch_and_deploy_gh_release "ots" "Luzifer/ots" "tarball" "latest" "/opt/ots" "ots_linux_amd64.tgz" -cat </opt/ots/env" +cat </opt/ots/env LISTEN=0.0.0.0:3000 REDIS_URL=redis://127.0.0.1:6379 SECRET_EXPIRY=604800 From ea6bffa79f0eea9d5bbf34c5d6220d5cf69bb580 Mon Sep 17 00:00:00 2001 From: Bas van den Berg <74251551+bvdberg01@users.noreply.github.com> Date: Sun, 20 Jul 2025 13:23:52 +0200 Subject: [PATCH 373/463] Update ots-install.sh --- install/ots-install.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/install/ots-install.sh b/install/ots-install.sh index 2c6b5f24..8ff32768 100644 --- a/install/ots-install.sh +++ b/install/ots-install.sh @@ -15,9 +15,7 @@ update_os msg_info "Installing Dependencies" $STD apt-get install -y \ - caddy \ - apt-transport-https \ - ca-certificates + redis-server msg_ok "Installed Dependencies" msg_info "Installing OTS" From d2f96c89b7f0352b4f95cb25d2cb2eb0b512c77b Mon Sep 17 00:00:00 2001 From: Bas van den Berg <74251551+bvdberg01@users.noreply.github.com> Date: Sun, 20 Jul 2025 14:06:34 +0200 Subject: [PATCH 374/463] Update ots-install.sh --- install/ots-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/ots-install.sh b/install/ots-install.sh index 8ff32768..7c243b37 100644 --- a/install/ots-install.sh +++ b/install/ots-install.sh @@ -19,7 +19,7 @@ $STD apt-get install -y \ msg_ok "Installed Dependencies" msg_info "Installing OTS" -fetch_and_deploy_gh_release "ots" "Luzifer/ots" "tarball" "latest" "/opt/ots" "ots_linux_amd64.tgz" +fetch_and_deploy_gh_release "ots" "Luzifer/ots" "prebuild" "latest" "/opt/ots" "ots_linux_amd64.tgz" cat </opt/ots/env LISTEN=0.0.0.0:3000 REDIS_URL=redis://127.0.0.1:6379 From 00c131f7aaf2b7378c7c90959a546fa57efb36a6 Mon Sep 17 00:00:00 2001 From: Bas van den Berg <74251551+bvdberg01@users.noreply.github.com> Date: Sun, 20 Jul 2025 14:21:23 +0200 Subject: [PATCH 375/463] Update tools.func --- misc/tools.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/tools.func b/misc/tools.func index 6973e4c6..92a5bac5 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -968,7 +968,7 @@ function fetch_and_deploy_gh_release() { $STD apt-get install -y unzip fi unzip -q "$tmpdir/$filename" -d "$unpack_tmp" - elif [[ "$filename" == *.tar.* ]]; then + elif [[ "$filename" == *.tar.* || "$filename" == *.tgz ]]; then tar -xf "$tmpdir/$filename" -C "$unpack_tmp" else msg_error "Unsupported archive format: $filename" From 8ba183c6319b80af4c7f2cb98612258d3824a17a Mon Sep 17 00:00:00 2001 From: Bas van den Berg <74251551+bvdberg01@users.noreply.github.com> Date: Sun, 20 Jul 2025 15:14:27 +0200 Subject: [PATCH 376/463] Update ots-install.sh --- install/ots-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/ots-install.sh b/install/ots-install.sh index 7c243b37..514ce80d 100644 --- a/install/ots-install.sh +++ b/install/ots-install.sh @@ -44,6 +44,7 @@ RestartSecs=5 [Install] WantedBy=multi-user.target EOF +systemctl enable -q --now ots msg_ok "Created Services" motd_ssh From af1c0726cbd357bb6b9f832e8d7d2b222d530c3a Mon Sep 17 00:00:00 2001 From: Bas van den Berg <74251551+bvdberg01@users.noreply.github.com> Date: Sun, 20 Jul 2025 15:15:21 +0200 Subject: [PATCH 377/463] Update ots-install.sh --- install/ots-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/ots-install.sh b/install/ots-install.sh index 514ce80d..da8e1d55 100644 --- a/install/ots-install.sh +++ b/install/ots-install.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Copyright (c) 2021-2025 community-scripts ORG -# Author: MickLesk (CanbiZ) +# Author: bvberg01 # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE # Source: https://github.com/Luzifer/ots From 34113208ffd757a6106049a168ce466e50774878 Mon Sep 17 00:00:00 2001 From: Bas van den Berg <74251551+bvdberg01@users.noreply.github.com> Date: Sun, 20 Jul 2025 15:40:27 +0200 Subject: [PATCH 378/463] Update ots.sh --- ct/ots.sh | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/ct/ots.sh b/ct/ots.sh index d089bd80..e3e03df9 100644 --- a/ct/ots.sh +++ b/ct/ots.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) # Copyright (c) 2021-2025 community-scripts ORG -# Author: BvdBerg01 +# Author: bvdberg01 # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE # Source: https://github.com/Luzifer/ots APP="OTS" -var_tags="${var_tags:-analytics}" +var_tags="${var_tags:-secrets-sharer}" var_cpu="${var_cpu:-1}" var_ram="${var_ram:-512}" var_disk="${var_disk:-3}" @@ -27,10 +27,25 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi - msg_info "Updating $APP LXC" - $STD apt-get update - $STD apt-get -y upgrade - msg_ok "Updated $APP LXC" + + RELEASE=$(curl -fsSL https://api.github.com/repos/Luzifer/ots/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + + msg_info "Stopping ${APP} Service" + systemctl stop ots + msg_ok "Stopped ${APP} Service" + + msg_info "Updating ${APP} to v${RELEASE}" + fetch_and_deploy_gh_release "ots" "Luzifer/ots" "prebuild" "latest" "/opt/ots" "ots_linux_amd64.tgz" + msg_ok "Updated ${APP} to v${RELEASE}" + + msg_info "Stopping ${APP} Service" + systemctl start ots + msg_ok "Stopped ${APP} Service" + + else + msg_ok "No update required. ${APP} is already at ${RELEASE}" + fi exit } From 41b616ae2afa1d2c06084309786250f1d5055ed6 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 07:44:24 +0200 Subject: [PATCH 379/463] Update auto-update-app-headers.yml --- .github/workflows/auto-update-app-headers.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/auto-update-app-headers.yml b/.github/workflows/auto-update-app-headers.yml index 339ed4c4..30bc5f42 100644 --- a/.github/workflows/auto-update-app-headers.yml +++ b/.github/workflows/auto-update-app-headers.yml @@ -24,13 +24,18 @@ jobs: with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} + owner: community-scripts + repositories: ProxmoxVED + - name: Generate a token for PR approval and merge id: generate-token-merge uses: actions/create-github-app-token@v2 with: - app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }} - private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }} + app-id: ${{ vars.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + owner: community-scripts + repositories: ProxmoxVED # Step 1: Checkout repository - name: Checkout repository From a7e8207c41037d04d7cda0f5c86428af640e4704 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 21 Jul 2025 05:45:14 +0000 Subject: [PATCH 380/463] Update .app files --- ct/headers/cloudreve | 6 ++++++ ct/headers/leantime | 6 ++++++ ct/headers/nginxproxymanager | 6 ++++++ ct/headers/reactive-resume | 6 ------ ct/headers/salt | 6 ++++++ ct/headers/saltmaster | 6 ------ ct/headers/tududi | 6 ++++++ 7 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 ct/headers/cloudreve create mode 100644 ct/headers/leantime create mode 100644 ct/headers/nginxproxymanager delete mode 100644 ct/headers/reactive-resume create mode 100644 ct/headers/salt delete mode 100644 ct/headers/saltmaster create mode 100644 ct/headers/tududi diff --git a/ct/headers/cloudreve b/ct/headers/cloudreve new file mode 100644 index 00000000..fb88b4ab --- /dev/null +++ b/ct/headers/cloudreve @@ -0,0 +1,6 @@ + ________ __ + / ____/ /___ __ ______/ /_______ _ _____ + / / / / __ \/ / / / __ / ___/ _ \ | / / _ \ +/ /___/ / /_/ / /_/ / /_/ / / / __/ |/ / __/ +\____/_/\____/\__,_/\__,_/_/ \___/|___/\___/ + diff --git a/ct/headers/leantime b/ct/headers/leantime new file mode 100644 index 00000000..048d615d --- /dev/null +++ b/ct/headers/leantime @@ -0,0 +1,6 @@ + __ __ _ + / / ___ ____ _____ / /_(_)___ ___ ___ + / / / _ \/ __ `/ __ \/ __/ / __ `__ \/ _ \ + / /___/ __/ /_/ / / / / /_/ / / / / / / __/ +/_____/\___/\__,_/_/ /_/\__/_/_/ /_/ /_/\___/ + diff --git a/ct/headers/nginxproxymanager b/ct/headers/nginxproxymanager new file mode 100644 index 00000000..d68d0c9d --- /dev/null +++ b/ct/headers/nginxproxymanager @@ -0,0 +1,6 @@ + _ __ _ ____ __ ___ + / | / /___ _(_)___ _ __ / __ \_________ _ ____ __ / |/ /___ _____ ____ _____ ____ _____ + / |/ / __ `/ / __ \| |/_/ / /_/ / ___/ __ \| |/_/ / / / / /|_/ / __ `/ __ \/ __ `/ __ `/ _ \/ ___/ + / /| / /_/ / / / / /> < / ____/ / / /_/ /> Date: Mon, 21 Jul 2025 07:48:43 +0200 Subject: [PATCH 381/463] fixes --- .../workflows/backup/update_json_date.yml.bak | 2 ++ .github/workflows/changelog-pr.yaml | 4 +++ .github/workflows/delete_new_script.yaml | 2 ++ .github/workflows/get-versions-from-gh.yaml | 2 ++ .../get-versions-from-newreleases.yaml | 4 +++ .github/workflows/live/changelog-pr.yml | 26 ++++++++++--------- .github/workflows/live/update-json-date.yml | 10 ++++--- 7 files changed, 34 insertions(+), 16 deletions(-) diff --git a/.github/workflows/backup/update_json_date.yml.bak b/.github/workflows/backup/update_json_date.yml.bak index cb9bc855..236a14b8 100644 --- a/.github/workflows/backup/update_json_date.yml.bak +++ b/.github/workflows/backup/update_json_date.yml.bak @@ -21,6 +21,8 @@ jobs: with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} + owner: community-scripts + repositories: ProxmoxVED - name: Checkout repository uses: actions/checkout@v4 diff --git a/.github/workflows/changelog-pr.yaml b/.github/workflows/changelog-pr.yaml index ca187dd5..300ce186 100644 --- a/.github/workflows/changelog-pr.yaml +++ b/.github/workflows/changelog-pr.yaml @@ -23,6 +23,8 @@ jobs: with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} + owner: community-scripts + repositories: ProxmoxVED - name: Generate a token for PR approval and merge id: generate-token-merge @@ -30,6 +32,8 @@ jobs: with: app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }} private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }} + owner: community-scripts + repositories: ProxmoxVED - name: Checkout code uses: actions/checkout@v4 diff --git a/.github/workflows/delete_new_script.yaml b/.github/workflows/delete_new_script.yaml index 9d9f97d6..468573c1 100644 --- a/.github/workflows/delete_new_script.yaml +++ b/.github/workflows/delete_new_script.yaml @@ -20,6 +20,8 @@ jobs: with: app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }} private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }} + owner: community-scripts + repositories: ProxmoxVED - name: Extract Issue Title (Lowercase & Underscores) id: extract_title diff --git a/.github/workflows/get-versions-from-gh.yaml b/.github/workflows/get-versions-from-gh.yaml index d3cd7e36..d45532e2 100644 --- a/.github/workflows/get-versions-from-gh.yaml +++ b/.github/workflows/get-versions-from-gh.yaml @@ -28,6 +28,8 @@ jobs: with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} + owner: community-scripts + repositories: ProxmoxVED - name: Crawl from Github API env: diff --git a/.github/workflows/get-versions-from-newreleases.yaml b/.github/workflows/get-versions-from-newreleases.yaml index aabfae35..9d06d6c6 100644 --- a/.github/workflows/get-versions-from-newreleases.yaml +++ b/.github/workflows/get-versions-from-newreleases.yaml @@ -28,6 +28,8 @@ jobs: with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} + owner: community-scripts + repositories: ProxmoxVED - name: Generate a token for PR approval and merge id: generate-token-merge @@ -35,6 +37,8 @@ jobs: with: app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }} private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }} + owner: community-scripts + repositories: ProxmoxVED - name: Crawl from newreleases.io env: diff --git a/.github/workflows/live/changelog-pr.yml b/.github/workflows/live/changelog-pr.yml index dc5bcd3d..f3bb1cbd 100644 --- a/.github/workflows/live/changelog-pr.yml +++ b/.github/workflows/live/changelog-pr.yml @@ -22,6 +22,8 @@ jobs: with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} + owner: community-scripts + repositories: ProxmoxVED - name: Checkout code uses: actions/checkout@v4 @@ -109,7 +111,7 @@ jobs: ); if (updateScriptsCategory) { - + const subCategory = updateScriptsCategory.subCategories.find(sub => sub.labels.some(label => prLabels.includes(label)) ); @@ -121,7 +123,7 @@ jobs: } } }); - + console.log(JSON.stringify(categorizedPRs, null, 2)); return categorizedPRs; @@ -147,30 +149,30 @@ jobs: const hasSubcategories = subCategories && subCategories.length > 0; const hasMainNotes = notes.length > 0; const hasSubNotes = hasSubcategories && subCategories.some(sub => sub.notes && sub.notes.length > 0); - - + + if (hasMainNotes || hasSubNotes) { newReleaseNotes += `### ${title}\n\n`; } - + if (hasMainNotes) { newReleaseNotes += ` ${notes.join("\n")}\n\n`; } if (hasSubcategories) { for (const { title: subTitle, notes: subNotes } of subCategories) { if (subNotes && subNotes.length > 0) { - newReleaseNotes += ` - #### ${subTitle}\n\n`; - newReleaseNotes += ` ${subNotes.join("\n ")}\n\n`; + newReleaseNotes += ` - #### ${subTitle}\n\n`; + newReleaseNotes += ` ${subNotes.join("\n ")}\n\n`; } } } - } - + } + const changelogContent = await fs.readFile(changelogPath, 'utf-8'); const changelogIncludesTodaysReleaseNotes = changelogContent.includes(`\n## ${today}`); - const regex = changelogIncludesTodaysReleaseNotes - ? new RegExp(`## ${today}.*(?=## ${latestDateInChangelog})`, "gs") + const regex = changelogIncludesTodaysReleaseNotes + ? new RegExp(`## ${today}.*(?=## ${latestDateInChangelog})`, "gs") : new RegExp(`(?=## ${latestDateInChangelog})`, "gs"); const newChangelogContent = changelogContent.replace(regex, newReleaseNotes); @@ -223,4 +225,4 @@ jobs: PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number') if [ -n "$PR_NUMBER" ]; then gh pr review $PR_NUMBER --approve - fi \ No newline at end of file + fi diff --git a/.github/workflows/live/update-json-date.yml b/.github/workflows/live/update-json-date.yml index 7e9c2497..861c4ee0 100644 --- a/.github/workflows/live/update-json-date.yml +++ b/.github/workflows/live/update-json-date.yml @@ -6,7 +6,7 @@ on: - main paths: - 'json/**.json' - workflow_dispatch: + workflow_dispatch: jobs: update-app-files: @@ -23,11 +23,13 @@ jobs: with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} + owner: community-scripts + repositories: ProxmoxVED - name: Generate dynamic branch name id: timestamp run: echo "BRANCH_NAME=pr-update-json-$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV - + - name: Set up GH_TOKEN env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -102,8 +104,8 @@ jobs: - name: Commit and create PR if changes exist if: env.changed == 'true' run: | - - + + git commit -m "Update date in json" git checkout -b ${{ env.BRANCH_NAME }} git push origin ${{ env.BRANCH_NAME }} From 23119da919344e6fd4c162aafc40d2e3fb149024 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 07:50:03 +0200 Subject: [PATCH 382/463] rm cloudreve --- ct/cloudreve.sh | 58 ----------------------------- frontend/public/json/cloudreve.json | 40 -------------------- install/cloudreve-install.sh | 43 --------------------- 3 files changed, 141 deletions(-) delete mode 100644 ct/cloudreve.sh delete mode 100644 frontend/public/json/cloudreve.json delete mode 100644 install/cloudreve-install.sh diff --git a/ct/cloudreve.sh b/ct/cloudreve.sh deleted file mode 100644 index ce5ee296..00000000 --- a/ct/cloudreve.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash -source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) -# Copyright (c) 2021-2025 community-scripts ORG -# Author: MickLesk (CanbiZ) -# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE -# Source: https://cloudreve.org/ - -APP="Cloudreve" -var_tags="${var_tags:-cloud}" -var_cpu="${var_cpu:-1}" -var_ram="${var_ram:-1024}" -var_disk="${var_disk:-10}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -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/cloudreve ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - - RELEASE=$(curl -fsSL https://api.github.com/repos/cloudreve/cloudreve/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - if [[ "${RELEASE}" != "$(cat ~/.cloudreve 2>/dev/null)" ]] || [[ ! -f ~/.cloudreve ]]; then - msg_info "Stopping $APP" - systemctl stop cloudreve - msg_ok "Stopped $APP" - - fetch_and_deploy_gh_release "cloudreve" "cloudreve/cloudreve" "prebuild" "latest" "/opt/cloudreve" "*linux_amd64.tar.gz" - - msg_info "Starting $APP" - systemctl start cloudreve - msg_ok "Started $APP" - - msg_ok "Update Successful" - else - msg_ok "No update required. ${APP} is already at v${RELEASE}" - 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}http://${IP}:5212${CL}" diff --git a/frontend/public/json/cloudreve.json b/frontend/public/json/cloudreve.json deleted file mode 100644 index 61fa2ce0..00000000 --- a/frontend/public/json/cloudreve.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "Cloudreve", - "slug": "cloudreve", - "categories": [ - 12 - ], - "date_created": "2025-07-17", - "type": "ct", - "updateable": false, - "privileged": false, - "interface_port": 5212, - "documentation": "https://docs.cloudreve.org/en/", - "website": "https://cloudreve.org/", - "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/cloudreve.webp", - "config_path": "/opt/cloudreve/data/config.ini", - "description": "Cloudreve is an open-source, community-driven cloud storage system that provides file sharing, synchronization, and management features. It supports a wide range of storage backends and integrates with various notification and logging platforms.", - "install_methods": [ - { - "type": "default", - "script": "ct/cloudreve.sh", - "resources": { - "cpu": 1, - "ram": 1024, - "hdd": 10, - "os": "Debian", - "version": "12" - } - } - ], - "default_credentials": { - "username": null, - "password": null - }, - "notes": [ - { - "text": "After Installation: Register your user -> Login -> Dashboard -> Accept Primary URL.", - "type": "warn" - } - ] -} diff --git a/install/cloudreve-install.sh b/install/cloudreve-install.sh deleted file mode 100644 index c7ef56fa..00000000 --- a/install/cloudreve-install.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 community-scripts ORG -# Author: MickLesk (CanbiZ) -# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE -# Source: https://cloudreve.org/ - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -fetch_and_deploy_gh_release "cloudreve" "cloudreve/cloudreve" "prebuild" "latest" "/opt/cloudreve" "*linux_amd64.tar.gz" - -msg_info "Setup Service" -cat </etc/systemd/system/cloudreve.service -[Unit] -Description=Cloudreve Service -After=network.target - -[Service] -Type=simple -ExecStart=/opt/cloudreve/cloudreve -Restart=on-failure -RestartSec=5 - -[Install] -WantedBy=multi-user.target -EOF - -systemctl enable -q --now cloudreve -msg_ok "Service Setup" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" From e23e84dd22a9a658c8928e3f9367406bf936f082 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 07:50:46 +0200 Subject: [PATCH 383/463] token v2 --- .github/workflows/backup/update_json_date.yml.bak | 2 +- .github/workflows/changelog-pr.yaml | 4 ++-- .github/workflows/delete_new_script.yaml | 2 +- .github/workflows/get-versions-from-gh.yaml | 2 +- .github/workflows/get-versions-from-newreleases.yaml | 4 ++-- .github/workflows/live/changelog-pr.yml | 2 +- .github/workflows/live/update-json-date.yml | 2 +- .github/workflows/move-to-main-repo.yaml | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/backup/update_json_date.yml.bak b/.github/workflows/backup/update_json_date.yml.bak index 236a14b8..71012528 100644 --- a/.github/workflows/backup/update_json_date.yml.bak +++ b/.github/workflows/backup/update_json_date.yml.bak @@ -17,7 +17,7 @@ jobs: steps: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@v1 + uses: actions/create-github-app-token@v2 with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} diff --git a/.github/workflows/changelog-pr.yaml b/.github/workflows/changelog-pr.yaml index 300ce186..80959d54 100644 --- a/.github/workflows/changelog-pr.yaml +++ b/.github/workflows/changelog-pr.yaml @@ -19,7 +19,7 @@ jobs: steps: - name: Generate a token for PR creation id: generate-token - uses: actions/create-github-app-token@v1 + uses: actions/create-github-app-token@v2 with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} @@ -28,7 +28,7 @@ jobs: - name: Generate a token for PR approval and merge id: generate-token-merge - uses: actions/create-github-app-token@v1 + uses: actions/create-github-app-token@v2 with: app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }} private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }} diff --git a/.github/workflows/delete_new_script.yaml b/.github/workflows/delete_new_script.yaml index 468573c1..d538437a 100644 --- a/.github/workflows/delete_new_script.yaml +++ b/.github/workflows/delete_new_script.yaml @@ -16,7 +16,7 @@ jobs: - name: Generate a token for PR approval and merge id: generate-token-merge - uses: actions/create-github-app-token@v1 + uses: actions/create-github-app-token@v2 with: app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }} private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }} diff --git a/.github/workflows/get-versions-from-gh.yaml b/.github/workflows/get-versions-from-gh.yaml index d45532e2..0cf632d1 100644 --- a/.github/workflows/get-versions-from-gh.yaml +++ b/.github/workflows/get-versions-from-gh.yaml @@ -24,7 +24,7 @@ jobs: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@v1 + uses: actions/create-github-app-token@v2 with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} diff --git a/.github/workflows/get-versions-from-newreleases.yaml b/.github/workflows/get-versions-from-newreleases.yaml index 9d06d6c6..634a0c1b 100644 --- a/.github/workflows/get-versions-from-newreleases.yaml +++ b/.github/workflows/get-versions-from-newreleases.yaml @@ -24,7 +24,7 @@ jobs: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@v1 + uses: actions/create-github-app-token@v2 with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} @@ -33,7 +33,7 @@ jobs: - name: Generate a token for PR approval and merge id: generate-token-merge - uses: actions/create-github-app-token@v1 + uses: actions/create-github-app-token@v2 with: app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }} private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }} diff --git a/.github/workflows/live/changelog-pr.yml b/.github/workflows/live/changelog-pr.yml index f3bb1cbd..87da5514 100644 --- a/.github/workflows/live/changelog-pr.yml +++ b/.github/workflows/live/changelog-pr.yml @@ -18,7 +18,7 @@ jobs: steps: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@v1 + uses: actions/create-github-app-token@v2 with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} diff --git a/.github/workflows/live/update-json-date.yml b/.github/workflows/live/update-json-date.yml index 861c4ee0..1bf965a4 100644 --- a/.github/workflows/live/update-json-date.yml +++ b/.github/workflows/live/update-json-date.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@v1 + uses: actions/create-github-app-token@v2 with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} diff --git a/.github/workflows/move-to-main-repo.yaml b/.github/workflows/move-to-main-repo.yaml index 9c9fb65d..dfddeff7 100644 --- a/.github/workflows/move-to-main-repo.yaml +++ b/.github/workflows/move-to-main-repo.yaml @@ -18,7 +18,7 @@ jobs: steps: - name: Generate a token id: app-token - uses: actions/create-github-app-token@v1 + uses: actions/create-github-app-token@v2 with: app-id: ${{ vars.PUSH_MAIN_APP_ID }} private-key: ${{ secrets.PUSH_MAIN_APP_SECRET }} From 687890f663f923bca8ac7b8f6177e2c6a995a3f7 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 09:14:51 +0200 Subject: [PATCH 384/463] rm docker --- ct/docker.sh | 92 ------------------------------ install/docker-install.sh | 114 -------------------------------------- 2 files changed, 206 deletions(-) delete mode 100644 ct/docker.sh delete mode 100644 install/docker-install.sh diff --git a/ct/docker.sh b/ct/docker.sh deleted file mode 100644 index 123d0c7c..00000000 --- a/ct/docker.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2025 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://www.docker.com/ - -APP="Docker" -var_tags="${var_tags:-docker}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-2048}" -var_disk="${var_disk:-4}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -var_unprivileged="${var_unprivileged:-1}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - header_info - check_container_storage - check_container_resources - - get_latest_release() { - curl -fsSL https://api.github.com/repos/"$1"/releases/latest | grep '"tag_name":' | cut -d'"' -f4 - } - - msg_info "Updating base system" - $STD apt-get update - $STD apt-get -y upgrade - msg_ok "Base system updated" - - msg_info "Updating Docker Engine" - $STD apt-get install --only-upgrade -y docker-ce docker-ce-cli containerd.io - msg_ok "Docker Engine updated" - - if [[ -f /usr/local/lib/docker/cli-plugins/docker-compose ]]; then - COMPOSE_BIN="/usr/local/lib/docker/cli-plugins/docker-compose" - COMPOSE_NEW_VERSION=$(get_latest_release "docker/compose") - msg_info "Updating Docker Compose to $COMPOSE_NEW_VERSION" - curl -fsSL "https://github.com/docker/compose/releases/download/${COMPOSE_NEW_VERSION}/docker-compose-$(uname -s)-$(uname -m)" \ - -o "$COMPOSE_BIN" - chmod +x "$COMPOSE_BIN" - msg_ok "Docker Compose updated" - fi - - if docker ps -a --format '{{.Names}}' | grep -q '^portainer$'; then - msg_info "Updating Portainer" - docker pull portainer/portainer-ce:latest - docker stop portainer && docker rm portainer - docker volume create portainer_data >/dev/null 2>&1 - $STD docker run -d \ - -p 8000:8000 \ - -p 9443:9443 \ - --name=portainer \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v portainer_data:/data \ - portainer/portainer-ce:latest - msg_ok "Updated Portainer" - fi - - if docker ps -a --format '{{.Names}}' | grep -q '^portainer_agent$'; then - msg_info "Updating Portainer Agent" - docker pull portainer/agent:latest - docker stop portainer_agent && docker rm portainer_agent - $STD docker run -d \ - -p 9001:9001 \ - --name=portainer_agent \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /var/lib/docker/volumes:/var/lib/docker/volumes \ - portainer/agent - msg_ok "Updated Portainer Agent" - fi - - msg_info "Cleaning up" - $STD apt-get -y autoremove - $STD apt-get -y autoclean - msg_ok "Cleanup complete" - exit -} - -start -build_container -description - -msg_ok "Completed Successfully!\n" -echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" diff --git a/install/docker-install.sh b/install/docker-install.sh deleted file mode 100644 index 238a8404..00000000 --- a/install/docker-install.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://www.docker.com/ - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -get_latest_release() { - curl -fsSL https://api.github.com/repos/"$1"/releases/latest | grep '"tag_name":' | cut -d'"' -f4 -} - -DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") -PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") -PORTAINER_AGENT_LATEST_VERSION=$(get_latest_release "portainer/agent") -DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") - -msg_info "Installing Docker $DOCKER_LATEST_VERSION" -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json -$STD sh <(curl -fsSL https://get.docker.com) -msg_ok "Installed Docker $DOCKER_LATEST_VERSION" - -read -r -p "${TAB3}Install Docker Compose v2 plugin? " prompt_compose -if [[ ${prompt_compose,,} =~ ^(y|yes)$ ]]; then - msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" - mkdir -p /usr/local/lib/docker/cli-plugins - curl -fsSL "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_LATEST_VERSION}/docker-compose-$(uname -s)-$(uname -m)" \ - -o /usr/local/lib/docker/cli-plugins/docker-compose - chmod +x /usr/local/lib/docker/cli-plugins/docker-compose - msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" -fi - -read -r -p "${TAB3}Would you like to add Portainer (UI)? " prompt -if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then - msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" - docker volume create portainer_data >/dev/null - $STD docker run -d \ - -p 8000:8000 \ - -p 9443:9443 \ - --name=portainer \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v portainer_data:/data \ - portainer/portainer-ce:latest - msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" -else - read -r -p "${TAB3}Would you like to install the Portainer Agent (for remote management)? " prompt_agent - if [[ ${prompt_agent,,} =~ ^(y|yes)$ ]]; then - msg_info "Installing Portainer Agent $PORTAINER_AGENT_LATEST_VERSION" - $STD docker run -d \ - -p 9001:9001 \ - --name portainer_agent \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /var/lib/docker/volumes:/var/lib/docker/volumes \ - portainer/agent - msg_ok "Installed Portainer Agent $PORTAINER_AGENT_LATEST_VERSION" - fi -fi - -read -r -p "${TAB3}Expose Docker TCP socket (insecure) ? [n = No, l = Local only (127.0.0.1), a = All interfaces (0.0.0.0)] : " socket_choice -case "${socket_choice,,}" in - l) - socket="tcp://127.0.0.1:2375" - ;; - a) - socket="tcp://0.0.0.0:2375" - ;; - *) - socket="" - ;; -esac - -if [[ -n "$socket" ]]; then - msg_info "Enabling Docker TCP socket on $socket" - $STD apt-get install -y jq - - tmpfile=$(mktemp) - jq --arg sock "$socket" '. + { "hosts": ["unix:///var/run/docker.sock", $sock] }' /etc/docker/daemon.json > "$tmpfile" && mv "$tmpfile" /etc/docker/daemon.json - - mkdir -p /etc/systemd/system/docker.service.d - cat < /etc/systemd/system/docker.service.d/override.conf -[Service] -ExecStart= -ExecStart=/usr/bin/dockerd -EOF - - $STD systemctl daemon-reexec - $STD systemctl daemon-reload - - if systemctl restart docker; then - msg_ok "Docker TCP socket available on $socket" - else - msg_error "Docker failed to restart. Check journalctl -xeu docker.service" - exit 1 - fi -fi - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" From 3e562048a6f2a749cb0269128beb0d7f7b1b3694 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 21 Jul 2025 07:15:21 +0000 Subject: [PATCH 385/463] Update .app files --- ct/headers/cloudreve | 6 ------ ct/headers/docker | 6 ------ 2 files changed, 12 deletions(-) delete mode 100644 ct/headers/cloudreve delete mode 100644 ct/headers/docker diff --git a/ct/headers/cloudreve b/ct/headers/cloudreve deleted file mode 100644 index fb88b4ab..00000000 --- a/ct/headers/cloudreve +++ /dev/null @@ -1,6 +0,0 @@ - ________ __ - / ____/ /___ __ ______/ /_______ _ _____ - / / / / __ \/ / / / __ / ___/ _ \ | / / _ \ -/ /___/ / /_/ / /_/ / /_/ / / / __/ |/ / __/ -\____/_/\____/\__,_/\__,_/_/ \___/|___/\___/ - diff --git a/ct/headers/docker b/ct/headers/docker deleted file mode 100644 index 907ffbae..00000000 --- a/ct/headers/docker +++ /dev/null @@ -1,6 +0,0 @@ - ____ __ - / __ \____ _____/ /_____ _____ - / / / / __ \/ ___/ //_/ _ \/ ___/ - / /_/ / /_/ / /__/ ,< / __/ / -/_____/\____/\___/_/|_|\___/_/ - From 715bd48f9f7a2aed3fe8d7477369d031971a4b5c Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 09:27:23 +0200 Subject: [PATCH 386/463] docspell --- ct/docspell.sh | 2 +- install/docspell-install.sh | 60 +++++++++---------------------------- 2 files changed, 15 insertions(+), 47 deletions(-) diff --git a/ct/docspell.sh b/ct/docspell.sh index 7fcdc014..3ff1cd3b 100644 --- a/ct/docspell.sh +++ b/ct/docspell.sh @@ -3,7 +3,7 @@ source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/ # Copyright (c) 2021-2025 community-scripts ORG # Author: MickLesk (Canbiz) # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: +# Source: https://github.com/community-scripts/ProxmoxVE APP="Docspell" var_tags="${var_tags:-document}" diff --git a/install/docspell-install.sh b/install/docspell-install.sh index b9bb74ad..14d908fc 100644 --- a/install/docspell-install.sh +++ b/install/docspell-install.sh @@ -20,11 +20,8 @@ msg_ok "Setup Functions" msg_info "Installing Dependencies (Patience)" $STD apt-get install -y \ htop \ - gnupg2 \ ca-certificates \ - default-jdk \ apt-transport-https \ - ghostscript \ tesseract-ocr \ tesseract-ocr-deu \ tesseract-ocr-eng \ @@ -34,13 +31,13 @@ $STD apt-get install -y \ ocrmypdf msg_ok "Installed Dependencies" -msg_info "Setting up PostgreSQL Repository" -curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg -echo "deb https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" >/etc/apt/sources.list.d/pgdg.list -$STD apt-get update -msg_ok "Set up PostgreSQL Repository" -msg_info "Install/Set up PostgreSQL Database" +setup_gs +JAVA_VERSION="21" setup_java +POSTGRES_VERSION="16" setup_postgres +setup_yq + +msg_info "Set up PostgreSQL Database" $STD apt-get install -y postgresql-16 DB_NAME=docspell_db DB_USER=docspell_usr @@ -58,23 +55,15 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';" } >>~/docspell.creds msg_ok "Set up PostgreSQL Database" -msg_info "Setup Docspell (Patience)" -mkdir -p /opt/docspell -Docspell=$(curl -fsSL https://github.com/eikek/docspell/releases/latest -o - | grep "title>Release" | cut -d " " -f 5) -DocspellDSC=$(curl -fsSL https://github.com/docspell/dsc/releases/latest -o - | grep "title>Release" | cut -d " " -f 4 | sed 's/^v//') -cd /opt -curl -fsSL https://github.com/eikek/docspell/releases/download/v${Docspell}/docspell-joex_${Docspell}_all.deb -o docspell-joex_${Docspell}_all.deb -curl -fsSL https://github.com/eikek/docspell/releases/download/v${Docspell}/docspell-restserver_${Docspell}_all.deb -o docspell-restserver_${Docspell}_all.deb -$STD dpkg -i docspell-*.deb -curl -fsSL https://github.com/docspell/dsc/releases/download/v${DocspellDSC}/dsc_amd64-musl-${DocspellDSC} -o dsc_amd64-musl-${DocspellDSC} -mv dsc_amd* dsc -chmod +x dsc -mv dsc /usr/bin + +fetch_and_deploy_gh_release "docspell-joex" "eikek/docspell" "binary" "latest" "/opt/docspell-joex" "docspell-joex_*all.deb" +fetch_and_deploy_gh_release "docspell-restserver" "eikek/docspell" "binary" "latest" "/opt/docspell-restserver" "docspell-restserver_*all.deb" +fetch_and_deploy_gh_release "docspell-dsc" "docspell/dsc" "singlefile" "latest" "/usr/bin" "dsc" + + + +msg_info "Setup Docspell" ln -s /etc/docspell-joex /opt/docspell/docspell-joex && ln -s /etc/docspell-restserver /opt/docspell/docspell-restserver && ln -s /usr/bin/dsc /opt/docspell/dsc -curl -fsSL https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -o /usr/bin/yq -chmod +x /usr/bin/yq -#JOEX_CONF="/usr/share/docspell-joex/conf/docspell-joex.conf" -#SERVER_CONF="/usr/share/docspell-restserver/conf/docspell-server.conf" sed -i \ -e '11s|localhost|'"$LOCAL_IP"'|' \ -e '17s|localhost|'"$LOCAL_IP"'|' \ @@ -94,27 +83,6 @@ sed -i \ -e '358s|password = .*|password = "'"$DB_PASS"'"|' \ -e '401s|url = .*|url = "jdbc:postgresql://localhost:5432/'"$DB_NAME"'"|' \ /usr/share/docspell-restserver/conf/docspell-server.conf - -# sed -i 's|address = "localhost"|address = "0.0.0.0"|' "$JOEX_CONF" "$SERVER_CONF" -# sed -i -E '/backend\s*\{/,/\}/ { -# /jdbc\s*\{/,/\}/ { -# s|(url\s*=\s*).*|\1"jdbc:postgresql://localhost:5432/'"$DB_NAME"'"|; -# s|(user\s*=\s*).*|\1"'"$DB_USER"'"|; -# s|(password\s*=\s*).*|\1"'"$DB_PASS"'"|; -# } -# }' "$SERVER_CONF" -# sed -i -E '/postgresql\s*\{/,/\}/ { -# /jdbc\s*\{/,/\}/ { -# s|(url\s*=\s*).*|\1"jdbc:postgresql://localhost:5432/'"$DB_NAME"'"|; -# s|(user\s*=\s*).*|\1"'"$DB_USER"'"|; -# s|(password\s*=\s*).*|\1"'"$DB_PASS"'"|; -# } -# }' "$SERVER_CONF" -# sed -i -E '/jdbc\s*\{/,/\}/ { -# s|(url\s*=\s*).*|\1"jdbc:postgresql://localhost:5432/'"$DB_NAME"'"|; -# s|(user\s*=\s*).*|\1"'"$DB_USER"'"|; -# s|(password\s*=\s*).*|\1"'"$DB_PASS"'"|; -# }' "$JOEX_CONF" msg_ok "Setup Docspell" msg_info "Setup Apache Solr" From 436026dc1cef5730d80d7a1f19ddc517f345b2bd Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 11:44:41 +0200 Subject: [PATCH 387/463] Update build.func --- misc/build.func | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/misc/build.func b/misc/build.func index 50664ea8..35c623ed 100644 --- a/misc/build.func +++ b/misc/build.func @@ -77,15 +77,37 @@ root_check() { # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { - if ! pveversion | grep -Eq "pve-manager/8\.[0-4](\.[0-9]+)*"; then - msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported" - echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." - echo -e "Exiting..." - sleep 2 - exit + local PVE_VER + PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')" + + # 8 Version Check + if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then + local MINOR="${BASH_REMATCH[1]}" + if (( MINOR < 1 || MINOR > 4 )); then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires Proxmox Virtual Environment Version 8.1 – 8.4" + echo -e "Exiting..." + sleep 2 + exit 1 + fi + return 0 fi + + # 9 Beta Version Check + if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then + msg_custom "Detected Proxmox Virtual Environment $PVE_VER – Beta state, use with caution!" + return 0 + fi + + # All others (unsupported versions) + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires Proxmox Virtual Environment Version 8.1 – 8.4 or 9.x (Beta)" + echo -e "Exiting..." + sleep 2 + exit 1 } + # When a node is running tens of containers, it's possible to exceed the kernel's cryptographic key storage allocations. # These are tuneable, so verify if the currently deployment is approaching the limits, advise the user on how to tune the limits, and exit the script. # https://cleveruptime.com/docs/files/proc-key-users | https://docs.kernel.org/security/keys/core.html From 8a875044f04e1eb0ccfea39b7ce4f77d7f18b034 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 11:59:23 +0200 Subject: [PATCH 388/463] testing & remove some things --- install/docspell-install.sh | 16 +- misc/backup_07052025/alpine-install copy.func | 277 ---- misc/backup_07052025/api.func.bak | 189 --- misc/backup_07052025/backup.func | 139 -- misc/backup_07052025/build copy.func | 1407 ----------------- misc/backup_07052025/core.func.bak | 220 --- misc/backup_07052025/dialogue.bak | 850 ---------- misc/backup_07052025/install copy.func | 281 ---- misc/backup_07052025/msg.func | 98 -- 9 files changed, 8 insertions(+), 3469 deletions(-) delete mode 100644 misc/backup_07052025/alpine-install copy.func delete mode 100644 misc/backup_07052025/api.func.bak delete mode 100644 misc/backup_07052025/backup.func delete mode 100644 misc/backup_07052025/build copy.func delete mode 100644 misc/backup_07052025/core.func.bak delete mode 100644 misc/backup_07052025/dialogue.bak delete mode 100644 misc/backup_07052025/install copy.func delete mode 100644 misc/backup_07052025/msg.func diff --git a/install/docspell-install.sh b/install/docspell-install.sh index 14d908fc..d76983d2 100644 --- a/install/docspell-install.sh +++ b/install/docspell-install.sh @@ -22,19 +22,19 @@ $STD apt-get install -y \ htop \ ca-certificates \ apt-transport-https \ - tesseract-ocr \ - tesseract-ocr-deu \ - tesseract-ocr-eng \ - unpaper \ - unoconv \ - wkhtmltopdf \ - ocrmypdf + tesseract-ocr + #tesseract-ocr-deu \ + #tesseract-ocr-eng \ + #unpaper \ + #unoconv \ + #wkhtmltopdf \ + #ocrmypdf msg_ok "Installed Dependencies" setup_gs JAVA_VERSION="21" setup_java -POSTGRES_VERSION="16" setup_postgres +POSTGRES_VERSION="16" setup_postgresql setup_yq msg_info "Set up PostgreSQL Database" diff --git a/misc/backup_07052025/alpine-install copy.func b/misc/backup_07052025/alpine-install copy.func deleted file mode 100644 index 71e7c1d4..00000000 --- a/misc/backup_07052025/alpine-install copy.func +++ /dev/null @@ -1,277 +0,0 @@ -# Copyright (c) 2021-2025 tteck -# Author: tteck (tteckster) -# Co-Author: MickLesk -# License: MIT -# https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE - -source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) -load_functions - -# This function sets color variables for formatting output in the terminal -# color() { -# # Colors -# YW=$(echo "\033[33m") -# YWB=$(echo "\033[93m") -# BL=$(echo "\033[36m") -# RD=$(echo "\033[01;31m") -# GN=$(echo "\033[1;92m") - -# # Formatting -# CL=$(echo "\033[m") -# BFR="\\r\\033[K" -# BOLD=$(echo "\033[1m") -# TAB=" " - -# # System -# RETRY_NUM=10 -# RETRY_EVERY=3 -# i=$RETRY_NUM - -# # Icons -# CM="${TAB}✔️${TAB}${CL}" -# CROSS="${TAB}✖️${TAB}${CL}" -# INFO="${TAB}💡${TAB}${CL}" -# NETWORK="${TAB}📡${TAB}${CL}" -# OS="${TAB}🖥️${TAB}${CL}" -# OSVERSION="${TAB}🌟${TAB}${CL}" -# HOSTNAME="${TAB}🏠${TAB}${CL}" -# GATEWAY="${TAB}🌐${TAB}${CL}" -# DEFAULT="${TAB}⚙️${TAB}${CL}" -# } - -# Function to set STD mode based on verbosity -set_std_mode() { - if [ "$VERBOSE" = "yes" ]; then - STD="" - else - STD="silent" - fi -} - -# Silent execution function -silent() { - "$@" >/dev/null 2>&1 -} - -# This function enables IPv6 if it's not disabled and sets verbose mode -verb_ip6() { - set_std_mode # Set STD mode based on VERBOSE - - if [ "$DISABLEIPV6" == "yes" ]; then - $STD sysctl -w net.ipv6.conf.all.disable_ipv6=1 - echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf - $STD rc-update add sysctl default - fi -} - -# This function catches errors and handles them with the error handler function -catch_errors() { - unset SPINNER_PID - set -Eeuo pipefail - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -} - -# This function handles errors -error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" - [[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" &>/dev/null || true -} - -# # This function displays an informational message with logging support. -# declare -A MSG_INFO_SHOWN -# SPINNER_ACTIVE=0 -# SPINNER_PID="" -# SPINNER_MSG="" - -# trap 'stop_spinner' EXIT INT TERM HUP - -# start_spinner() { -# local msg="$1" -# local frames=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏) -# local spin_i=0 -# local interval=0.1 - -# SPINNER_MSG="$msg" -# printf "\r\e[2K" >&2 - -# { -# while [[ "$SPINNER_ACTIVE" -eq 1 ]]; do -# printf "\r\e[2K%s %b" "${frames[spin_i]}" "${YW}${SPINNER_MSG}${CL}" >&2 -# spin_i=$(((spin_i + 1) % ${#frames[@]})) -# sleep "$interval" -# done -# } & - -# SPINNER_PID=$! -# disown "$SPINNER_PID" -# } - -# stop_spinner() { -# if [[ ${SPINNER_PID+v} && -n "$SPINNER_PID" ]] && kill -0 "$SPINNER_PID" 2>/dev/null; then -# kill "$SPINNER_PID" 2>/dev/null -# sleep 0.1 -# kill -0 "$SPINNER_PID" 2>/dev/null && kill -9 "$SPINNER_PID" 2>/dev/null -# wait "$SPINNER_PID" 2>/dev/null || true -# fi -# SPINNER_ACTIVE=0 -# unset SPINNER_PID -# } - -# spinner_guard() { -# if [[ "$SPINNER_ACTIVE" -eq 1 ]] && [[ -n "$SPINNER_PID" ]]; then -# kill "$SPINNER_PID" 2>/dev/null -# wait "$SPINNER_PID" 2>/dev/null || true -# SPINNER_ACTIVE=0 -# unset SPINNER_PID -# fi -# } - -# msg_info() { -# local msg="$1" -# [[ -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return -# MSG_INFO_SHOWN["$msg"]=1 - -# spinner_guard -# SPINNER_ACTIVE=1 -# start_spinner "$msg" -# } - -# msg_ok() { -# local msg="$1" -# stop_spinner -# printf "\r\e[2K%s %b\n" "${CM}" "${GN}${msg}${CL}" >&2 -# unset MSG_INFO_SHOWN["$msg"] -# } - -# msg_error() { -# stop_spinner -# local msg="$1" -# printf "\r\e[2K%s %b\n" "${CROSS}" "${RD}${msg}${CL}" >&2 -# #log_message "ERROR" "$msg" -# } - -# This function sets up the Container OS by generating the locale, setting the timezone, and checking the network connection -setting_up_container() { - msg_info "Setting up Container OS" - while [ $i -gt 0 ]; do - if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - i=$((i - 1)) - done - - if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e "${NETWORK}Check Network Settings" - exit 1 - fi - msg_ok "Set up Container OS" - msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" -} - -# This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected -network_check() { - set +e - trap - ERR - if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then - msg_ok "Internet Connected" - else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e "${INFO}${RD}Expect Issues Without Internet${CL}" - else - echo -e "${NETWORK}Check Network Settings" - exit 1 - fi - fi - RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') - if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi - set -e - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -} - -# This function updates the Container OS by running apt-get update and upgrade -update_os() { - msg_info "Updating Container OS" - $STD apk update - $STD apk upgrade - msg_ok "Updated Container OS" - - msg_info "Installing core dependencies" - $STD apk update - $STD apk add newt curl openssh nano mc ncurses - msg_ok "Core dependencies installed" -} - -# This function modifies the message of the day (motd) and SSH settings -motd_ssh() { - echo "export TERM='xterm-256color'" >>/root/.bashrc - IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) - - if [ -f "/etc/os-release" ]; then - OS_NAME=$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '"') - OS_VERSION=$(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"') - else - OS_NAME="Alpine Linux" - OS_VERSION="Unknown" - fi - - PROFILE_FILE="/etc/profile.d/00_lxc-details.sh" - echo "echo -e \"\"" >"$PROFILE_FILE" - echo -e "echo -e \"${BOLD}${YW}${APPLICATION} LXC Container - DEV Repository${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${RD}WARNING: This is a DEVELOPMENT version (ProxmoxVED). Do NOT use in production!${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} IP Address: ${GN}${IP}${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} Repository: ${GN}https://github.com/community-scripts/ProxmoxVED${CL}\"" >>"$PROFILE_FILE" - echo "echo \"\"" >>"$PROFILE_FILE" - - if [[ "${SSH_ROOT}" == "yes" ]]; then - $STD rc-update add sshd - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - $STD /etc/init.d/sshd start - fi -} - -# Validate Timezone for some LXC's -validate_tz() { - [[ -f "/usr/share/zoneinfo/$1" ]] -} - -# This function customizes the container and enables passwordless login for the root user -customize() { - if [[ "$PASSWORD" == "" ]]; then - msg_info "Customizing Container" - passwd -d root >/dev/null 2>&1 - - # Ensure agetty is available - apk add --no-cache --force-broken-world util-linux >/dev/null 2>&1 - - # Create persistent autologin boot script - mkdir -p /etc/local.d - cat <<'EOF' >/etc/local.d/autologin.start -#!/bin/sh -sed -i 's|^tty1::respawn:.*|tty1::respawn:/sbin/agetty --autologin root --noclear tty1 38400 linux|' /etc/inittab -kill -HUP 1 -EOF - touch /root/.hushlogin - - chmod +x /etc/local.d/autologin.start - rc-update add local >/dev/null 2>&1 - - # Apply autologin immediately for current session - /etc/local.d/autologin.start - - msg_ok "Customized Container" - fi - - echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update - chmod +x /usr/bin/update -} diff --git a/misc/backup_07052025/api.func.bak b/misc/backup_07052025/api.func.bak deleted file mode 100644 index 2da17c1b..00000000 --- a/misc/backup_07052025/api.func.bak +++ /dev/null @@ -1,189 +0,0 @@ -# Copyright (c) 2021-2025 community-scripts ORG -# Author: michelroegl-brunner -# License: MIT | https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/LICENSE - -get_error_description() { - local exit_code="$1" - case "$exit_code" in - 0) echo " " ;; - 1) echo "General error: An unspecified error occurred." ;; - 2) echo "Incorrect shell usage or invalid command arguments." ;; - 3) echo "Unexecuted function or invalid shell condition." ;; - 4) echo "Error opening a file or invalid path." ;; - 5) echo "I/O error: An input/output failure occurred." ;; - 6) echo "No such device or address." ;; - 7) echo "Insufficient memory or resource exhaustion." ;; - 8) echo "Non-executable file or invalid file format." ;; - 9) echo "Failed child process execution." ;; - 18) echo "Connection to a remote server failed." ;; - 22) echo "Invalid argument or faulty network connection." ;; - 28) echo "No space left on device." ;; - 35) echo "Timeout while establishing a connection." ;; - 56) echo "Faulty TLS connection." ;; - 60) echo "SSL certificate error." ;; - 100) echo "LXC install error: Unexpected error in create_lxc.sh." ;; - 101) echo "LXC install error: No network connection detected." ;; - 200) echo "LXC creation failed." ;; - 201) echo "LXC error: Invalid Storage class." ;; - 202) echo "User aborted menu in create_lxc.sh." ;; - 203) echo "CTID not set in create_lxc.sh." ;; - 204) echo "PCT_OSTYPE not set in create_lxc.sh." ;; - 205) echo "CTID cannot be less than 100 in create_lxc.sh." ;; - 206) echo "CTID already in use in create_lxc.sh." ;; - 207) echo "Template not found in create_lxc.sh." ;; - 208) echo "Error downloading template in create_lxc.sh." ;; - 209) echo "Container creation failed, but template is intact in create_lxc.sh." ;; - 125) echo "Docker error: Container could not start." ;; - 126) echo "Command not executable: Incorrect permissions or missing dependencies." ;; - 127) echo "Command not found: Incorrect path or missing dependency." ;; - 128) echo "Invalid exit signal, e.g., incorrect Git command." ;; - 129) echo "Signal 1 (SIGHUP): Process terminated due to hangup." ;; - 130) echo "Signal 2 (SIGINT): Manual termination via Ctrl+C." ;; - 132) echo "Signal 4 (SIGILL): Illegal machine instruction." ;; - 133) echo "Signal 5 (SIGTRAP): Debugging error or invalid breakpoint signal." ;; - 134) echo "Signal 6 (SIGABRT): Program aborted itself." ;; - 135) echo "Signal 7 (SIGBUS): Memory error, invalid memory address." ;; - 137) echo "Signal 9 (SIGKILL): Process forcibly terminated (OOM-killer or 'kill -9')." ;; - 139) echo "Signal 11 (SIGSEGV): Segmentation fault, possibly due to invalid pointer access." ;; - 141) echo "Signal 13 (SIGPIPE): Pipe closed unexpectedly." ;; - 143) echo "Signal 15 (SIGTERM): Process terminated normally." ;; - 152) echo "Signal 24 (SIGXCPU): CPU time limit exceeded." ;; - 255) echo "Unknown critical error, often due to missing permissions or broken scripts." ;; - *) echo "Unknown error code ($exit_code)." ;; - esac -} - -post_to_api() { - - if ! command -v curl &>/dev/null; then - return - fi - - if [ "$DIAGNOSTICS" = "no" ]; then - return - fi - - if [ -z "$RANDOM_UUID" ]; then - return - fi - - local API_URL="http://api.community-scripts.org/dev/upload" - local pve_version="not found" - pve_version=$(pveversion | awk -F'[/ ]' '{print $2}') - - JSON_PAYLOAD=$( - cat </dev/null; then - return - fi - - if [ "$POST_UPDATE_DONE" = true ]; then - return 0 - fi - exit_code=${2:-1} - local API_URL="http://api.community-scripts.org/dev/upload/updatestatus" - local status="${1:-failed}" - if [[ "$status" == "failed" ]]; then - local exit_code="${2:-1}" - elif [[ "$status" == "success" ]]; then - local exit_code="${2:-0}" - fi - - if [[ -z "$exit_code" ]]; then - exit_code=1 - fi - - error=$(get_error_description "$exit_code") - - if [ -z "$error" ]; then - error="Unknown error" - fi - - JSON_PAYLOAD=$( - cat <, sonst Arbeitsverzeichnis oder APP_DIR gesetzt vom Script - base_dir="${APP_DIR:-/opt/$app_name}" - if [[ ! -d "$base_dir" ]]; then - msg_error "Cannot determine base directory for $app_name" - return 1 - fi - - local snapshot_base="${base_dir}-snapshot" - SNAPSHOT_DIR="${snapshot_base}-$(date +%F_%T | tr ':' '-')" - - msg_info "Creating snapshot for $app_name" - - mkdir -p "$SNAPSHOT_DIR" - cp -a "$base_dir" "$SNAPSHOT_DIR/base" || { - msg_error "Failed to backup base directory" - return 1 - } - - mkdir -p "$SNAPSHOT_DIR/systemd" - cp -a /etc/systemd/system/${app_name}-*.service "$SNAPSHOT_DIR/systemd/" 2>/dev/null || true - - [[ -f "/etc/default/$app_name" ]] && cp "/etc/default/$app_name" "$SNAPSHOT_DIR/" - [[ -f "$base_dir/${app_name}_version.txt" ]] && cp "$base_dir/${app_name}_version.txt" "$SNAPSHOT_DIR/" - - rotate_snapshots "$snapshot_base" - - msg_ok "Snapshot created at $SNAPSHOT_DIR" - return 0 -} - -rotate_snapshots() { - local snapshot_base=$1 - local snapshots - - # Sortiert nach Datum absteigend, behalte nur die 3 neuesten - mapfile -t snapshots < <(ls -dt ${snapshot_base}-* 2>/dev/null) - if ((${#snapshots[@]} > 3)); then - for ((i = 3; i < ${#snapshots[@]}; i++)); do - rm -rf "${snapshots[$i]}" - msg_info "Old snapshot removed: ${snapshots[$i]}" - done - fi -} - -rollback_snapshot() { - local app_name=$1 - local base_dir - - base_dir="${APP_DIR:-/opt/$app_name}" - if [[ -z "$SNAPSHOT_DIR" || ! -d "$SNAPSHOT_DIR" ]]; then - msg_error "No snapshot found. Cannot rollback." - return 1 - fi - - msg_info "Rolling back $app_name from snapshot" - - systemctl stop ${app_name}-* 2>/dev/null || true - - rm -rf "$base_dir" - cp -a "$SNAPSHOT_DIR/base" "$base_dir" || { - msg_error "Failed to restore base directory" - return 1 - } - - if [[ -d "$SNAPSHOT_DIR/systemd" ]]; then - cp "$SNAPSHOT_DIR/systemd/"*.service /etc/systemd/system/ 2>/dev/null || true - systemctl daemon-reload - fi - - [[ -f "$SNAPSHOT_DIR/$app_name" ]] && cp "$SNAPSHOT_DIR/$app_name" "/etc/default/$app_name" - [[ -f "$SNAPSHOT_DIR/${app_name}_version.txt" ]] && cp "$SNAPSHOT_DIR/${app_name}_version.txt" "$base_dir/" - - systemctl start ${app_name}-* 2>/dev/null || true - - msg_ok "Rollback for $app_name completed" - return 0 -} - -cleanup_snapshot() { - if [[ -n "$SNAPSHOT_DIR" && -d "$SNAPSHOT_DIR" ]]; then - rm -rf "$SNAPSHOT_DIR" - msg_ok "Cleaned up snapshot at $SNAPSHOT_DIR" - fi -} - -handle_failure() { - local app_name=$1 - local line=$2 - msg_error "Update failed at line $line. Rolling back..." - rollback_snapshot "$app_name" - exit 1 -} - -safe_run_update_script() { - local app_name="${APP:-paperless}" - - if ! create_snapshot "$app_name"; then - msg_error "Snapshot creation failed. Aborting update." - exit 1 - fi - - trap 'handle_failure "$app_name" $LINENO' ERR - set -eE - - update_script - - cleanup_snapshot -} - -wrap_update_script_with_snapshot() { - local original_func - original_func=$(declare -f update_script) || return 1 - - eval " - original_update_script() { - ${original_func#*\{} - } - update_script() { - local app_name=\"\${APP:-paperless}\" - if ! create_snapshot \"\$app_name\"; then - msg_error \"Snapshot creation failed. Aborting update.\" - exit 1 - fi - trap 'handle_failure \"\$app_name\" \$LINENO' ERR - set -eE - original_update_script - cleanup_snapshot - } - " -} diff --git a/misc/backup_07052025/build copy.func b/misc/backup_07052025/build copy.func deleted file mode 100644 index bf5af2c4..00000000 --- a/misc/backup_07052025/build copy.func +++ /dev/null @@ -1,1407 +0,0 @@ -# Copyright (c) 2021-2025 tteck -# Author: tteck (tteckster) -# Co-Author: MickLesk -# Co-Author: michelroegl-brunner -# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE - -variables() { - NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. - var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. - INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. - PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase - DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call. - METHOD="default" # sets the METHOD variable to "default", used for the API call. - RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable. -} - -source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) - -source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) -color - -# # This function sets various color variables using ANSI escape codes for formatting text in the terminal. -# color() { -# # Colors -# YW=$(echo "\033[33m") -# YWB=$(echo "\033[93m") -# BL=$(echo "\033[36m") -# RD=$(echo "\033[01;31m") -# BGN=$(echo "\033[4;92m") -# GN=$(echo "\033[1;92m") -# DGN=$(echo "\033[32m") - -# # Formatting -# CL=$(echo "\033[m") -# BOLD=$(echo "\033[1m") -# HOLD=" " -# TAB=" " - -# # Icons -# CM="${TAB}✔️${TAB}" -# CROSS="${TAB}✖️${TAB}" -# INFO="${TAB}💡${TAB}${CL}" -# OS="${TAB}🖥️${TAB}${CL}" -# OSVERSION="${TAB}🌟${TAB}${CL}" -# CONTAINERTYPE="${TAB}📦${TAB}${CL}" -# DISKSIZE="${TAB}💾${TAB}${CL}" -# CPUCORE="${TAB}🧠${TAB}${CL}" -# RAMSIZE="${TAB}🛠️${TAB}${CL}" -# SEARCH="${TAB}🔍${TAB}${CL}" -# VERBOSE_CROPPED="🔍${TAB}" -# VERIFYPW="${TAB}🔐${TAB}${CL}" -# CONTAINERID="${TAB}🆔${TAB}${CL}" -# HOSTNAME="${TAB}🏠${TAB}${CL}" -# BRIDGE="${TAB}🌉${TAB}${CL}" -# NETWORK="${TAB}📡${TAB}${CL}" -# GATEWAY="${TAB}🌐${TAB}${CL}" -# DISABLEIPV6="${TAB}🚫${TAB}${CL}" -# DEFAULT="${TAB}⚙️${TAB}${CL}" -# MACADDRESS="${TAB}🔗${TAB}${CL}" -# VLANTAG="${TAB}🏷️${TAB}${CL}" -# ROOTSSH="${TAB}🔑${TAB}${CL}" -# CREATING="${TAB}🚀${TAB}${CL}" -# ADVANCED="${TAB}🧩${TAB}${CL}" -# } - -# This function enables error handling in the script by setting options and defining a trap for the ERR signal. -catch_errors() { - set -Eeuo pipefail - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -} - -# This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. -error_handler() { - source /dev/stdin <<<$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) - if [ -n "$SPINNER_PID" ] && ps -p "$SPINNER_PID" >/dev/null; then kill "$SPINNER_PID" >/dev/null; fi - printf "\e[?25h" - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - post_update_to_api "failed" "${command}" - echo -e "\n$error_message\n" -} - -# Check if the shell is using bash -shell_check() { - if [[ "$(basename "$SHELL")" != "bash" ]]; then - clear - msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." - echo -e "\nExiting..." - sleep 2 - exit - fi -} - -# Run as root only -root_check() { - if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then - clear - msg_error "Please run this script as root." - echo -e "\nExiting..." - sleep 2 - exit - fi -} - -# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. -pve_check() { - if ! pveversion | grep -Eq "pve-manager/8\.[0-4](\.[0-9]+)*"; then - msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported" - echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." - echo -e "Exiting..." - sleep 2 - exit - fi -} - -# When a node is running tens of containers, it's possible to exceed the kernel's cryptographic key storage allocations. -# These are tuneable, so verify if the currently deployment is approaching the limits, advise the user on how to tune the limits, and exit the script. -# https://cleveruptime.com/docs/files/proc-key-users | https://docs.kernel.org/security/keys/core.html -maxkeys_check() { - # Read kernel parameters - per_user_maxkeys=$(cat /proc/sys/kernel/keys/maxkeys 2>/dev/null || echo 0) - per_user_maxbytes=$(cat /proc/sys/kernel/keys/maxbytes 2>/dev/null || echo 0) - - # Exit if kernel parameters are unavailable - if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then - echo -e "${CROSS}${RD} Error: Unable to read kernel parameters. Ensure proper permissions.${CL}" - exit 1 - fi - - # Fetch key usage for user ID 100000 (typical for containers) - used_lxc_keys=$(awk '/100000:/ {print $2}' /proc/key-users 2>/dev/null || echo 0) - used_lxc_bytes=$(awk '/100000:/ {split($5, a, "/"); print a[1]}' /proc/key-users 2>/dev/null || echo 0) - - # Calculate thresholds and suggested new limits - threshold_keys=$((per_user_maxkeys - 100)) - threshold_bytes=$((per_user_maxbytes - 1000)) - new_limit_keys=$((per_user_maxkeys * 2)) - new_limit_bytes=$((per_user_maxbytes * 2)) - - # Check if key or byte usage is near limits - failure=0 - if [[ "$used_lxc_keys" -gt "$threshold_keys" ]]; then - echo -e "${CROSS}${RD} Warning: Key usage is near the limit (${used_lxc_keys}/${per_user_maxkeys}).${CL}" - echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxkeys=${new_limit_keys}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." - failure=1 - fi - if [[ "$used_lxc_bytes" -gt "$threshold_bytes" ]]; then - echo -e "${CROSS}${RD} Warning: Key byte usage is near the limit (${used_lxc_bytes}/${per_user_maxbytes}).${CL}" - echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxbytes=${new_limit_bytes}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." - failure=1 - fi - - # Provide next steps if issues are detected - if [[ "$failure" -eq 1 ]]; then - echo -e "${INFO} To apply changes, run: ${BOLD}service procps force-reload${CL}" - exit 1 - fi - - echo -e "${CM}${GN} All kernel key limits are within safe thresholds.${CL}" -} - -# This function checks the system architecture and exits if it's not "amd64". -arch_check() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n" - echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -# Function to get the current IP address based on the distribution -get_current_ip() { - if [ -f /etc/os-release ]; then - # Check for Debian/Ubuntu (uses hostname -I) - if grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then - CURRENT_IP=$(hostname -I | awk '{print $1}') - # Check for Alpine (uses ip command) - elif grep -q 'ID=alpine' /etc/os-release; then - CURRENT_IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) - else - CURRENT_IP="Unknown" - fi - fi - echo "$CURRENT_IP" -} - -# Function to update the IP address in the MOTD file -update_motd_ip() { - MOTD_FILE="/etc/motd" - - if [ -f "$MOTD_FILE" ]; then - # Remove existing IP Address lines to prevent duplication - sed -i '/IP Address:/d' "$MOTD_FILE" - - IP=$(get_current_ip) - # Add the new IP address - echo -e "${TAB}${NETWORK}${YW} IP Address: ${GN}${IP}${CL}" >>"$MOTD_FILE" - fi -} - -# Function to download & save header files -get_header() { - local app_name=$(echo "${APP,,}" | tr -d ' ') - local header_url="https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/ct/headers/${app_name}" - local local_header_path="/usr/local/community-scripts/headers/${app_name}" - - mkdir -p "$(dirname "$local_header_path")" - - if [ ! -s "$local_header_path" ]; then - if ! curl -fsSL "$header_url" -o "$local_header_path"; then - return 1 - fi - fi - - cat "$local_header_path" 2>/dev/null || true -} -# This function sets the APP-Name into an ASCII Header in Slant, figlet needed on proxmox main node. -header_info() { - local app_name=$(echo "${APP,,}" | tr -d ' ') - local header_content - - # Download & save Header-File locally - header_content=$(get_header "$app_name") || header_content="" - - # Show ASCII-Header - clear - local term_width - term_width=$(tput cols 2>/dev/null || echo 120) - - if [ -n "$header_content" ]; then - echo "$header_content" - fi -} - -# This function checks if the script is running through SSH and prompts the user to confirm if they want to proceed or exit. -ssh_check() { - if [ -n "${SSH_CLIENT:+x}" ]; then - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's advisable to utilize the Proxmox shell rather than SSH, as there may be potential complications with variable retrieval. Proceed using SSH?" 10 72; then - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Proceed using SSH" "You've chosen to proceed using SSH. If any issues arise, please run the script in the Proxmox shell before creating a repository issue." 10 72 - else - clear - echo "Exiting due to SSH usage. Please consider using the Proxmox shell." - exit - fi - fi -} - -base_settings() { - # Default Settings - CT_TYPE="1" - DISK_SIZE="4" - CORE_COUNT="1" - RAM_SIZE="1024" - VERBOSE="${1:-no}" - PW="" - CT_ID=$NEXTID - HN=$NSAPP - BRG="vmbr0" - NET="dhcp" - GATE="" - APT_CACHER="" - APT_CACHER_IP="" - DISABLEIP6="no" - MTU="" - SD="" - NS="" - MAC="" - VLAN="" - SSH="no" - SSH_AUTHORIZED_KEY="" - TAGS="community-script;" - UDHCPC_FIX="" - - # Override default settings with variables from ct script - CT_TYPE=${var_unprivileged:-$CT_TYPE} - DISK_SIZE=${var_disk:-$DISK_SIZE} - CORE_COUNT=${var_cpu:-$CORE_COUNT} - RAM_SIZE=${var_ram:-$RAM_SIZE} - VERB=${var_verbose:-$VERBOSE} - TAGS="${TAGS}${var_tags:-}" - - # Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts - if [ -z "$var_os" ]; then - var_os="debian" - fi - if [ -z "$var_version" ]; then - var_version="12" - fi -} - -# This function displays the default values for various settings. -echo_default() { - # Convert CT_TYPE to description - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi - - # Output the selected values with icons - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" - echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" - if [ "$VERB" == "yes" ]; then - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}" - fi - echo -e "${CREATING}${BOLD}${BL}Creating a ${APP} LXC using the above default settings${CL}" - echo -e " " -} - -# This function is called when the user decides to exit the script. It clears the screen and displays an exit message. -exit_script() { - [[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" &>/dev/null || true - clear - echo -e "\n${CROSS}${RD}User exited script${CL}\n" - exit -} - -# This function allows the user to configure advanced settings for the script. -advanced_settings() { - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 - # Setting Default Tag for Advanced Settings - TAGS="community-script;${var_tags:-}" - CT_DEFAULT_TYPE="${CT_TYPE}" - CT_TYPE="" - while [ -z "$CT_TYPE" ]; do - if [ "$CT_DEFAULT_TYPE" == "1" ]; then - if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - if [ -n "$CT_TYPE" ]; then - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - fi - else - exit_script - fi - fi - if [ "$CT_DEFAULT_TYPE" == "0" ]; then - if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3); then - if [ -n "$CT_TYPE" ]; then - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - fi - else - exit_script - fi - fi - done - - while true; do - if PW1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD (leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [[ ! -z "$PW1" ]]; then - if [[ "$PW1" == *" "* ]]; then - whiptail --msgbox "Password cannot contain spaces. Please try again." 8 58 - elif [ ${#PW1} -lt 5 ]; then - whiptail --msgbox "Password must be at least 5 characters long. Please try again." 8 58 - else - if PW2=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nVerify Root Password" 9 58 --title "PASSWORD VERIFICATION" 3>&1 1>&2 2>&3); then - if [[ "$PW1" == "$PW2" ]]; then - PW="-password $PW1" - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}********${CL}" - break - else - whiptail --msgbox "Passwords do not match. Please try again." 8 58 - fi - else - exit_script - fi - fi - else - PW1="Automatic Login" - PW="" - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}$PW1${CL}" - break - fi - else - exit_script - fi - done - - if CT_ID=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 "$NEXTID" --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi - else - exit - fi - - if CT_NAME=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 "$NSAPP" --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo "${CT_NAME,,}" | tr -d ' ') - fi - echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}" - else - exit_script - fi - - if DISK_SIZE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GB" 8 58 "$var_disk" --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "{INFO}${HOLD}${RD} DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" - fi - else - exit_script - fi - - if CORE_COUNT=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 "$var_cpu" --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}" - fi - else - exit_script - fi - - if RAM_SIZE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 "$var_ram" --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - else - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - fi - else - exit_script - fi - - if BRG=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" - else - echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" - fi - else - exit_script - fi - - while true; do - NET=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Static IPv4 CIDR Address (/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) - exit_status=$? - if [ $exit_status -eq 0 ]; then - if [ "$NET" = "dhcp" ]; then - echo -e "${NETWORK}${BOLD}${DGN}IP Address: ${BGN}$NET${CL}" - break - else - if [[ "$NET" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then - echo -e "${NETWORK}${BOLD}${DGN}IP Address: ${BGN}$NET${CL}" - break - else - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox "$NET is an invalid IPv4 CIDR address. Please enter a valid IPv4 CIDR address or 'dhcp'" 8 58 - fi - fi - else - exit_script - fi - done - - if [ "$NET" != "dhcp" ]; then - while true; do - GATE1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Enter gateway IP address" 8 58 --title "Gateway IP" 3>&1 1>&2 2>&3) - if [ -z "$GATE1" ]; then - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox "Gateway IP address cannot be empty" 8 58 - elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox "Invalid IP address format" 8 58 - else - GATE=",gw=$GATE1" - echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}$GATE1${CL}" - break - fi - done - else - GATE="" - echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}Default${CL}" - fi - - if [ "$var_os" == "alpine" ]; then - APT_CACHER="" - APT_CACHER_IP="" - else - if APT_CACHER_IP=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for none)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then - APT_CACHER="${APT_CACHER_IP:+yes}" - echo -e "${NETWORK}${BOLD}${DGN}APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" - else - exit_script - fi - fi - - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" - else - DISABLEIP6="no" - fi - echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - - if MTU1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default [The MTU of your selected vmbr, default is 1500])" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$MTU1" ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}" - else - exit_script - fi - - if SD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z "$SD" ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}$SX${CL}" - else - exit_script - fi - - if NX=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z "$NX" ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}$NX${CL}" - else - exit_script - fi - - if [ "$var_os" == "alpine" ] && [ "$NET" == "dhcp" ] && [ "$NX" != "Host" ]; then - UDHCPC_FIX="yes" - else - UDHCPC_FIX="no" - fi - export UDHCPC_FIX - - if MAC1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a MAC Address(leave blank for generated MAC)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z "$MAC1" ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}" - fi - else - exit_script - fi - - if VLAN1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for no VLAN)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z "$VLAN1" ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${VLANTAG}${BOLD}${DGN}Vlan: ${BGN}$VLAN1${CL}" - else - exit_script - fi - - if ADV_TAGS=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Custom Tags?[If you remove all, there will be no tags!]" 8 58 "${TAGS}" --title "Advanced Tags" 3>&1 1>&2 2>&3); then - if [ -n "${ADV_TAGS}" ]; then - ADV_TAGS=$(echo "$ADV_TAGS" | tr -d '[:space:]') - TAGS="${ADV_TAGS}" - else - TAGS=";" - fi - echo -e "${NETWORK}${BOLD}${DGN}Tags: ${BGN}$TAGS${CL}" - else - exit_script - fi - - if [[ "$PW" == -password* ]]; then - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" - else - SSH="no" - fi - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - else - SSH="no" - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - fi - - if [[ "${SSH}" == "yes" ]]; then - SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "SSH Authorized key for root (leave empty for none)" 8 58 --title "SSH Key" 3>&1 1>&2 2>&3)" - - if [[ -z "${SSH_AUTHORIZED_KEY}" ]]; then - echo "Warning: No SSH key provided." - fi - else - SSH_AUTHORIZED_KEY="" - fi - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" - else - VERB="no" - fi - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERB${CL}" - - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" - advanced_settings - fi -} - -diagnostics_check() { - if ! [ -d "/usr/local/community-scripts" ]; then - mkdir -p /usr/local/community-scripts - fi - - if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then - cat </usr/local/community-scripts/diagnostics -DIAGNOSTICS=yes - -#This file is used to store the diagnostics settings for the Community-Scripts API. -#https://github.com/community-scripts/ProxmoxVED/discussions/1836 -#Your diagnostics will be sent to the Community-Scripts API for troubleshooting/statistical purposes. -#You can review the data at https://community-scripts.github.io/ProxmoxVE/data -#If you do not wish to send diagnostics, please set the variable 'DIAGNOSTICS' to "no" in /usr/local/community-scripts/diagnostics, or use the menue. -#This will disable the diagnostics feature. -#To send diagnostics, set the variable 'DIAGNOSTICS' to "yes" in /usr/local/community-scripts/diagnostics, or use the menue. -#This will enable the diagnostics feature. -#The following information will be sent: -#"ct_type" -#"disk_size" -#"core_count" -#"ram_size" -#"os_type" -#"os_version" -#"disableip6" -#"nsapp" -#"method" -#"pve_version" -#"status" -#If you have any concerns, please review the source code at /misc/build.func -EOF - DIAGNOSTICS="yes" - else - cat </usr/local/community-scripts/diagnostics -DIAGNOSTICS=no - -#This file is used to store the diagnostics settings for the Community-Scripts API. -#https://github.com/community-scripts/ProxmoxVED/discussions/1836 -#Your diagnostics will be sent to the Community-Scripts API for troubleshooting/statistical purposes. -#You can review the data at https://community-scripts.github.io/ProxmoxVE/data -#If you do not wish to send diagnostics, please set the variable 'DIAGNOSTICS' to "no" in /usr/local/community-scripts/diagnostics, or use the menue. -#This will disable the diagnostics feature. -#To send diagnostics, set the variable 'DIAGNOSTICS' to "yes" in /usr/local/community-scripts/diagnostics, or use the menue. -#This will enable the diagnostics feature. -#The following information will be sent: -#"ct_type" -#"disk_size" -#"core_count" -#"ram_size" -#"os_type" -#"os_version" -#"disableip6" -#"nsapp" -#"method" -#"pve_version" -#"status" -#If you have any concerns, please review the source code at /misc/build.func -EOF - DIAGNOSTICS="no" - fi - else - DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' /usr/local/community-scripts/diagnostics) - - fi - -} - -config_file() { - - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Default distribution for $APP" "${var_os} ${var_version} \n \nIf the default Linux distribution is not adhered to, script support will be discontinued. \n" 10 58 - - CONFIG_FILE="/opt/community-scripts/.settings" - - if [[ -f "/opt/community-scripts/${NSAPP}.conf" ]]; then - CONFIG_FILE="/opt/community-scripts/${NSAPP}.conf" - fi - - if CONFIG_FILE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set absolute path to config file" 8 58 "$CONFIG_FILE" --title "CONFIG FILE" 3>&1 1>&2 2>&3); then - if [[ ! -f "$CONFIG_FILE" ]]; then - echo -e "${CROSS}${RD}Config file not found, exiting script!.${CL}" - exit - else - echo -e "${INFO}${BOLD}${DGN}Using config File: ${BGN}$CONFIG_FILE${CL}" - base_settings - source "$CONFIG_FILE" - fi - fi - - if [[ "$var_os" == "debian" ]]; then - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - if [[ "$var_version" == "11" ]]; then - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - elif [[ "$var_version" == "12" ]]; then - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - else - msg_error "Unknown setting for var_version, should be 11 or 12, was ${var_version}" - exit - fi - elif [[ "$var_os" == "ubuntu" ]]; then - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - if [[ "$var_version" == "20.04" ]]; then - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - elif [[ "$var_version" == "22.04" ]]; then - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - elif [[ "$var_version" == "24.04" ]]; then - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - elif [[ "$var_version" == "24.10" ]]; then - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - else - msg_error "Unknown setting for var_version, should be 20.04, 22.04, 24.04 or 24.10, was ${var_version}" - exit - fi - else - msg_error "Unknown setting for var_os! should be debian or ubuntu, was ${var_os}" - exit - fi - - if [[ -n "$CT_ID" ]]; then - - if [[ "$CT_ID" =~ ^([0-9]{3,4})-([0-9]{3,4})$ ]]; then - MIN_ID=${BASH_REMATCH[1]} - MAX_ID=${BASH_REMATCH[2]} - - if ((MIN_ID >= MAX_ID)); then - msg_error "Invalid Container ID range. The first number must be smaller than the second number, was ${CT_ID}" - exit - fi - - LIST_OF_IDS=$(pvesh get /cluster/resources --type vm --output-format json | grep -oP '"vmid":\s*\K\d+') - - for ((ID = MIN_ID; ID <= MAX_ID; ID++)); do - if ! grep -q "^$ID$" <<<"$LIST_OF_IDS"; then - CT_ID=$ID - break - fi - done - - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - - elif [[ "$CT_ID" =~ ^[0-9]+$ ]]; then - - LIST_OF_IDS=$(pvesh get /cluster/resources --type vm --output-format json | grep -oP '"vmid":\s*\K\d+') - if ! grep -q "^$CT_ID$" <<<"$LIST_OF_IDS"; then - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - msg_error "Container ID $CT_ID already exists" - exit - fi - else - msg_error "Invalid Container ID format. Needs to be 0000-9999 or 0-9999, was ${CT_ID}" - exit - fi - fi - - if [[ "$CT_TYPE" -eq 0 ]]; then - CT_TYPE_DESC="Privileged" - elif [[ "$CT_TYPE" -eq 1 ]]; then - CT_TYPE_DESC="Unprivileged" - else - msg_error "Unknown setting for CT_TYPE, should be 1 or 0, was ${CT_TYPE}" - exit - fi - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - - if [[ ! -z "$PW" ]]; then - - if [[ "$PW" == *" "* ]]; then - msg_error "Password cannot be empty" - exit - elif [[ ${#PW} -lt 5 ]]; then - msg_error "Password must be at least 5 characters long" - exit - else - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}********${CL}" - fi - PW="-password $PW" - else - PW="" - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}Automatic Login${CL}" - fi - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - - if [[ ! -z "$HN" ]]; then - echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}" - else - msg_error "Hostname cannot be empty" - exit - fi - - if [[ ! -z "$DISK_SIZE" ]]; then - if [[ "$DISK_SIZE" =~ ^-?[0-9]+$ ]]; then - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" - else - msg_error "DISK_SIZE must be an integer, was ${DISK_SIZE}" - exit - fi - else - msg_error "DISK_SIZE cannot be empty" - exit - fi - - if [[ ! -z "$CORE_COUNT" ]]; then - if [[ "$CORE_COUNT" =~ ^-?[0-9]+$ ]]; then - echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" - else - msg_error "CORE_COUNT must be an integer, was ${CORE_COUNT}" - exit - fi - else - msg_error "CORE_COUNT cannot be empty" - exit - fi - - if [[ ! -z "$RAM_SIZE" ]]; then - if [[ "$RAM_SIZE" =~ ^-?[0-9]+$ ]]; then - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - else - msg_error "RAM_SIZE must be an integer, was ${RAM_SIZE}" - exit - fi - else - msg_error "RAM_SIZE cannot be empty" - exit - fi - - if [[ ! -z "$BRG" ]]; then - if grep -q "^iface ${BRG}" /etc/network/interfaces; then - echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" - else - msg_error "Bridge '${BRG}' does not exist in /etc/network/interfaces" - exit - fi - else - msg_error "Bridge cannot be empty" - exit - fi - - local ip_cidr_regex='^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/([0-9]{1,2})$' - local ip_regex='^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$' - - if [[ ! -z $NET ]]; then - if [ "$NET" == "dhcp" ]; then - echo -e "${NETWORK}${BOLD}${DGN}IP Address: ${BGN}DHCP${CL}" - echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}Default${CL}" - elif - [[ "$NET" =~ $ip_cidr_regex ]] - then - echo -e "${NETWORK}${BOLD}${DGN}IP Address: ${BGN}$NET${CL}" - else - msg_error "Invalid IP Address format. Needs to be 0.0.0.0/0, was ${NET}" - exit - fi - fi - if [ ! -z "$GATE" ]; then - if [[ "$GATE" =~ $ip_regex ]]; then - echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}$GATE${CL}" - GATE=",gw=$GATE" - else - msg_error "Invalid IP Address format for Gateway. Needs to be 0.0.0.0, was ${GATE}" - exit - fi - else - msg_error "Gateway IP Address cannot be empty" - exit - fi - - if [[ ! -z "$APT_CACHER_IP" ]]; then - if [[ "$APT_CACHER_IP" =~ $ip_regex ]]; then - APT_CACHER="yes" - echo -e "${NETWORK}${BOLD}${DGN}APT-CACHER IP Address: ${BGN}$APT_CACHER_IP${CL}" - else - msg_error "Invalid IP Address format for APT-Cacher. Needs to be 0.0.0.0, was ${APT_CACHER_IP}" - exit - fi - fi - - if [[ "$DISABLEIP6" == "yes" ]]; then - echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}Yes${CL}" - elif [[ "$DISABLEIP6" == "no" ]]; then - echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}No${CL}" - else - msg_error "Disable IPv6 needs to be 'yes' or 'no'" - exit - fi - - if [[ ! -z "$MTU" ]]; then - if [[ "$MTU" =~ ^-?[0-9]+$ ]]; then - echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU${CL}" - MTU=",mtu=$MTU" - else - msg_error "MTU must be an integer, was ${MTU}" - exit - fi - else - MTU="" - echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}" - - fi - - if [[ ! -z "$SD" ]]; then - echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}$SD${CL}" - SD="-searchdomain=$SD" - else - SD="" - echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}HOST${CL}" - fi - - if [[ ! -z "$NS" ]]; then - if [[ "$NS" =~ $ip_regex ]]; then - echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}$NS${CL}" - NS="-nameserver=$NS" - else - msg_error "Invalid IP Address format for DNS Server. Needs to be 0.0.0.0, was ${NS}" - exit - fi - else - NS="" - echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}HOST${CL}" - fi - - if [[ ! -z "$MAC" ]]; then - if [[ "$MAC" =~ ^([A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}$ ]]; then - echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}" - MAC=",hwaddr=$MAC" - else - msg_error "MAC Address must be in the format xx:xx:xx:xx:xx:xx, was ${MAC}" - exit - fi - fi - - if [[ ! -z "$VLAN" ]]; then - if [[ "$VLAN" =~ ^-?[0-9]+$ ]]; then - echo -e "${VLANTAG}${BOLD}${DGN}Vlan: ${BGN}$VLAN${CL}" - VLAN=",tag=$VLAN" - else - msg_error "VLAN must be an integer, was ${VLAN}" - exit - fi - fi - - if [[ ! -z "$TAGS" ]]; then - echo -e "${NETWORK}${BOLD}${DGN}Tags: ${BGN}$TAGS${CL}" - fi - - if [[ "$SSH" == "yes" ]]; then - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - if [[ ! -z "$SSH_AUTHORIZED_KEY" ]]; then - echo -e "${ROOTSSH}${BOLD}${DGN}SSH Authorized Key: ${BGN}********************${CL}" - else - echo -e "${ROOTSSH}${BOLD}${DGN}SSH Authorized Key: ${BGN}None${CL}" - fi - elif [[ "$SSH" == "no" ]]; then - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - else - msg_error "SSH needs to be 'yes' or 'no', was ${SSH}" - exit - fi - - if [[ "$VERB" == "yes" ]]; then - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERB${CL}" - elif [[ "$VERB" == "no" ]]; then - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}No${CL}" - else - msg_error "Verbose Mode needs to be 'yes' or 'no', was ${VERB}" - exit - fi - - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS WITH CONFIG FILE COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above settings${CL}" - else - clear - header_info - echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" - config_file - fi - -} - -install_script() { - pve_check - shell_check - root_check - arch_check - ssh_check - maxkeys_check - diagnostics_check - - if systemctl is-active -q ping-instances.service; then - systemctl -q stop ping-instances.service - fi - NEXTID=$(pvesh get /cluster/nextid) - timezone=$(cat /etc/timezone) - header_info - while true; do - - CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SETTINGS" --menu "Choose an option:" \ - 18 60 6 \ - "1" "Default Settings" \ - "2" "Default Settings (with verbose)" \ - "3" "Advanced Settings" \ - "4" "Use Config File" \ - "5" "Diagnostic Settings" \ - "6" "Exit" --nocancel --default-item "1" 3>&1 1>&2 2>&3) - - if [ $? -ne 0 ]; then - echo -e "${CROSS}${RD} Menu canceled. Exiting.${CL}" - exit 0 - fi - - case $CHOICE in - 1) - header_info - echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME${CL}" - VERB="no" - METHOD="default" - base_settings "$VERB" - echo_default - break - ;; - 2) - header_info - echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME (${VERBOSE_CROPPED}Verbose)${CL}" - VERB="yes" - METHOD="default" - base_settings "$VERB" - echo_default - break - ;; - 3) - header_info - echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" - METHOD="advanced" - base_settings - advanced_settings - break - ;; - 4) - header_info - echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" - METHOD="advanced" - base_settings - config_file - break - ;; - 5) - if [[ $DIAGNOSTICS == "yes" ]]; then - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ - --yes-button "No" --no-button "Back"; then - DIAGNOSTICS="no" - sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 - fi - else - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ - --yes-button "Yes" --no-button "Back"; then - DIAGNOSTICS="yes" - sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 - fi - fi - - ;; - 6) - echo -e "${CROSS}${RD}Exiting.${CL}" - exit 0 - ;; - *) - echo -e "${CROSS}${RD}Invalid option, please try again.${CL}" - ;; - esac - done -} - -check_container_resources() { - # Check actual RAM & Cores - current_ram=$(free -m | awk 'NR==2{print $2}') - current_cpu=$(nproc) - - # Check whether the current RAM is less than the required RAM or the CPU cores are less than required - if [[ "$current_ram" -lt "$var_ram" ]] || [[ "$current_cpu" -lt "$var_cpu" ]]; then - echo -e "\n${INFO}${HOLD} ${GN}Required: ${var_cpu} CPU, ${var_ram}MB RAM ${CL}| ${RD}Current: ${current_cpu} CPU, ${current_ram}MB RAM${CL}" - echo -e "${YWB}Please ensure that the ${APP} LXC is configured with at least ${var_cpu} vCPU and ${var_ram} MB RAM for the build process.${CL}\n" - echo -ne "${INFO}${HOLD} May cause data loss! ${INFO} Continue update with under-provisioned LXC? " - read -r prompt - # Check if the input is 'yes', otherwise exit with status 1 - if [[ ! ${prompt,,} =~ ^(yes)$ ]]; then - echo -e "${CROSS}${HOLD} ${YWB}Exiting based on user input.${CL}" - exit 1 - fi - else - echo -e "" - fi -} - -check_container_storage() { - # Check if the /boot partition is more than 80% full - total_size=$(df /boot --output=size | tail -n 1) - local used_size=$(df /boot --output=used | tail -n 1) - usage=$((100 * used_size / total_size)) - if ((usage > 80)); then - # Prompt the user for confirmation to continue - echo -e "${INFO}${HOLD} ${YWB}Warning: Storage is dangerously low (${usage}%).${CL}" - echo -ne "Continue anyway? " - read -r prompt - # Check if the input is 'y' or 'yes', otherwise exit with status 1 - if [[ ! ${prompt,,} =~ ^(y|yes)$ ]]; then - echo -e "${CROSS}${HOLD}${YWB}Exiting based on user input.${CL}" - exit 1 - fi - fi -} - -start() { - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) - if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - exit_script - exit - fi - SPINNER_PID="" - install_script - else - CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC Update/Setting" --menu \ - "Support/Update functions for ${APP} LXC. Choose an option:" \ - 12 60 3 \ - "1" "YES (Silent Mode)" \ - "2" "YES (Verbose Mode)" \ - "3" "NO (Cancel Update)" --nocancel --default-item "1" 3>&1 1>&2 2>&3) - - case "$CHOICE" in - 1) - VERB="no" - set_std_mode - ;; - 2) - VERB="yes" - set_std_mode - ;; - 3) - clear - exit_script - exit - ;; - esac - - SPINNER_PID="" - update_script - fi -} - -# This function collects user settings and integrates all the collected information. -build_container() { - # if [ "$VERB" == "yes" ]; then set -x; fi - - if [ "$CT_TYPE" == "1" ]; then - FEATURES="keyctl=1,nesting=1" - else - FEATURES="nesting=1" - fi - - if [[ $DIAGNOSTICS == "yes" ]]; then - post_to_api - fi - - TEMP_DIR=$(mktemp -d) - pushd "$TEMP_DIR" >/dev/null - if [ "$var_os" == "alpine" ]; then - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)" - else - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)" - fi - export RANDOM_UUID="$RANDOM_UUID" - export CACHER="$APT_CACHER" - export CACHER_IP="$APT_CACHER_IP" - export tz="$timezone" - export DISABLEIPV6="$DISABLEIP6" - export APPLICATION="$APP" - export app="$NSAPP" - export PASSWORD="$PW" - export VERBOSE="$VERB" - export SSH_ROOT="${SSH}" - export SSH_AUTHORIZED_KEY - export CTID="$CT_ID" - export CTTYPE="$CT_TYPE" - export PCT_OSTYPE="$var_os" - export PCT_OSVERSION="$var_version" - export PCT_DISK_SIZE="$DISK_SIZE" - export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -tags $TAGS - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW - " - # This executes create_lxc.sh and creates the container and .conf file - bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)" $? - - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - if [ "$CT_TYPE" == "0" ]; then - cat <>"$LXC_CONFIG" -# USB passthrough -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF - fi - - if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then - cat <>$LXC_CONFIG -# VAAPI hardware transcoding -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file -EOF - fi - else - if [[ "$APP" == "immich" || "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then - if [[ -e "/dev/dri/renderD128" ]]; then - if [[ -e "/dev/dri/card0" ]]; then - cat <>$LXC_CONFIG -# VAAPI hardware transcoding -dev0: /dev/dri/card0,gid=44 -dev1: /dev/dri/renderD128,gid=104 -EOF - else - cat <>"$LXC_CONFIG" -# VAAPI hardware transcoding -dev0: /dev/dri/card1,gid=44 -dev1: /dev/dri/renderD128,gid=104 -EOF - fi - fi - fi - fi - - # This starts the container and executes -install.sh - msg_info "Starting LXC Container" - pct start "$CTID" - msg_ok "Started LXC Container" - if [ "$var_os" == "alpine" ]; then - sleep 3 - pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories -http://dl-cdn.alpinelinux.org/alpine/latest-stable/main -http://dl-cdn.alpinelinux.org/alpine/latest-stable/community -EOF' - pct exec "$CTID" -- ash -c "apk add bash >/dev/null" - fi - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/install/"$var_install".sh)" $? - -} - -# This function sets the description of the container. -description() { - IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - - # Generate LXC Description - DESCRIPTION=$( - cat < - - Logo - - -

${APP} LXC

- -

- - spend Coffee - -

- - - - GitHub - - - - Discussions - - - - Issues - - -EOF - ) - - # Set Description in LXC - pct set "$CTID" -description "$DESCRIPTION" - - if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service - fi - - post_update_to_api "done" "none" -} - -set_std_mode() { - if [ "$VERB" = "yes" ]; then - STD="" - else - STD="silent" - fi -} - -# Silent execution function -silent() { - if [ "$VERB" = "no" ]; then - "$@" >/dev/null 2>&1 || return 1 - else - "$@" || return 1 - fi -} - -api_exit_script() { - exit_code=$? # Capture the exit status of the last executed command - #200 exit codes indicate error in create_lxc.sh - #100 exit codes indicate error in install.func - - if [ $exit_code -ne 0 ]; then - case $exit_code in - 100) post_update_to_api "failed" "100: Unexpected error in create_lxc.sh" ;; - 101) post_update_to_api "failed" "101: No network connection detected in create_lxc.sh" ;; - 200) post_update_to_api "failed" "200: LXC creation failed in create_lxc.sh" ;; - 201) post_update_to_api "failed" "201: Invalid Storage class in create_lxc.sh" ;; - 202) post_update_to_api "failed" "202: User aborted menu in create_lxc.sh" ;; - 203) post_update_to_api "failed" "203: CTID not set in create_lxc.sh" ;; - 204) post_update_to_api "failed" "204: PCT_OSTYPE not set in create_lxc.sh" ;; - 205) post_update_to_api "failed" "205: CTID cannot be less than 100 in create_lxc.sh" ;; - 206) post_update_to_api "failed" "206: CTID already in use in create_lxc.sh" ;; - 207) post_update_to_api "failed" "207: Template not found in create_lxc.sh" ;; - 208) post_update_to_api "failed" "208: Error downloading template in create_lxc.sh" ;; - 209) post_update_to_api "failed" "209: Container creation failed, but template is intact in create_lxc.sh" ;; - *) post_update_to_api "failed" "Unknown error, exit code: $exit_code in create_lxc.sh" ;; - esac - fi -} - -trap 'api_exit_script' EXIT -trap 'post_update_to_api "failed" "$BASH_COMMAND"' ERR -trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT -trap 'post_update_to_api "failed" "TERMINATED"' SIGTERM diff --git a/misc/backup_07052025/core.func.bak b/misc/backup_07052025/core.func.bak deleted file mode 100644 index de18842a..00000000 --- a/misc/backup_07052025/core.func.bak +++ /dev/null @@ -1,220 +0,0 @@ -# Copyright (c) 2021-2025 community-scripts ORG -# Author: michelroegl-brunner -# License: MIT | https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/LICENSE - -color() { - # Colors - YW=$(echo "\033[33m") - YWB=$(echo "\033[93m") - BL=$(echo "\033[36m") - RD=$(echo "\033[01;31m") - BGN=$(echo "\033[4;92m") - GN=$(echo "\033[1;92m") - DGN=$(echo "\033[32m") - - # Formatting - CL=$(echo "\033[m") - BOLD=$(echo "\033[1m") - HOLD=" " - TAB=" " - - # Icons - CM="${TAB}✔️${TAB}" - CROSS="${TAB}✖️${TAB}${CL}" - INFO="${TAB}💡${TAB}${CL}" - OS="${TAB}🖥️${TAB}${CL}" - OSVERSION="${TAB}🌟${TAB}${CL}" - CONTAINERTYPE="${TAB}📦${TAB}${CL}" - DISKSIZE="${TAB}💾${TAB}${CL}" - CPUCORE="${TAB}🧠${TAB}${CL}" - RAMSIZE="${TAB}🛠️${TAB}${CL}" - SEARCH="${TAB}🔍${TAB}${CL}" - VERBOSE_CROPPED="🔍${TAB}" - VERIFYPW="${TAB}🔐${TAB}${CL}" - CONTAINERID="${TAB}🆔${TAB}${CL}" - HOSTNAME="${TAB}🏠${TAB}${CL}" - BRIDGE="${TAB}🌉${TAB}${CL}" - NETWORK="${TAB}📡${TAB}${CL}" - GATEWAY="${TAB}🌐${TAB}${CL}" - DISABLEIPV6="${TAB}🚫${TAB}${CL}" - DEFAULT="${TAB}⚙️${TAB}${CL}" - MACADDRESS="${TAB}🔗${TAB}${CL}" - VLANTAG="${TAB}🏷️${TAB}${CL}" - ROOTSSH="${TAB}🔑${TAB}${CL}" - CREATING="${TAB}🚀${TAB}${CL}" - ADVANCED="${TAB}🧩${TAB}${CL}" - FUSE="${TAB}🔧${TAB}${CL}" -} - -declare -A MSG_INFO_SHOWN -SPINNER_ACTIVE=0 -SPINNER_PID="" -SPINNER_MSG="" - -start_spinner() { - local msg="$1" - local frames=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏) - local spin_i=0 - local interval=0.1 - - SPINNER_MSG="$msg" - printf "\r\e[2K" >&2 - - { - while [[ "$SPINNER_ACTIVE" -eq 1 ]]; do - printf "\r\e[2K%s %b" "${frames[spin_i]}" "${YW}${SPINNER_MSG}${CL}" >&2 - spin_i=$(((spin_i + 1) % ${#frames[@]})) - sleep "$interval" - done - } & - - SPINNER_PID=$! - disown "$SPINNER_PID" -} - -stop_spinner() { - if [[ ${SPINNER_PID+v} && -n "$SPINNER_PID" ]] && kill -0 "$SPINNER_PID" 2>/dev/null; then - kill "$SPINNER_PID" 2>/dev/null - sleep 0.1 - kill -0 "$SPINNER_PID" 2>/dev/null && kill -9 "$SPINNER_PID" 2>/dev/null - wait "$SPINNER_PID" 2>/dev/null || true - fi - SPINNER_ACTIVE=0 - unset SPINNER_PID -} - -spinner_guard() { - if [[ "$SPINNER_ACTIVE" -eq 1 ]] && [[ -n "$SPINNER_PID" ]]; then - kill "$SPINNER_PID" 2>/dev/null - wait "$SPINNER_PID" 2>/dev/null || true - SPINNER_ACTIVE=0 - unset SPINNER_PID - fi -} - -log_message() { - local level="$1" - local message="$2" - local timestamp - local logdate - timestamp=$(date '+%Y-%m-%d %H:%M:%S') - logdate=$(date '+%Y-%m-%d') - - LOGDIR="/usr/local/community-scripts/logs" - mkdir -p "$LOGDIR" - - LOGFILE="${LOGDIR}/${logdate}_${NSAPP}.log" - echo "$timestamp - $level: $message" >>"$LOGFILE" -} - -msg_info() { - local msg="$1" - if [ "${SPINNER_ACTIVE:-0}" -eq 1 ]; then - return - fi - - SPINNER_ACTIVE=1 - start_spinner "$msg" -} - -msg_ok() { - if [ -n "${SPINNER_PID:-}" ] && ps -p "$SPINNER_PID" >/dev/null 2>&1; then - kill "$SPINNER_PID" >/dev/null 2>&1 - wait "$SPINNER_PID" 2>/dev/null || true - fi - - local msg="$1" - printf "\r\e[2K${CM}${GN}%b${CL}\n" "$msg" >&2 - unset SPINNER_PID - SPINNER_ACTIVE=0 - - log_message "OK" "$msg" -} - -msg_error() { - if [ -n "${SPINNER_PID:-}" ] && ps -p "$SPINNER_PID" >/dev/null 2>&1; then - kill "$SPINNER_PID" >/dev/null 2>&1 - wait "$SPINNER_PID" 2>/dev/null || true - fi - - local msg="$1" - printf "\r\e[2K${CROSS}${RD}%b${CL}\n" "$msg" >&2 - unset SPINNER_PID - SPINNER_ACTIVE=0 - log_message "ERROR" "$msg" -} - -shell_check() { - if [[ "$(basename "$SHELL")" != "bash" ]]; then - clear - msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." - echo -e "\nExiting..." - sleep 2 - exit - fi -} - -root_check() { - if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then - clear - msg_error "Please run this script as root." - echo -e "\nExiting..." - sleep 2 - exit - fi -} - -pve_check() { - if ! pveversion | grep -Eq "pve-manager/8\.[1-9](\.[0-9]+)*"; then - msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported" - echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." - echo -e "Exiting..." - sleep 2 - exit - fi -} - -arch_check() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n" - echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -ssh_check() { - if command -v pveversion >/dev/null 2>&1; then - if [ -n "${SSH_CLIENT:+x}" ]; then - if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then - echo "you've been warned" - else - clear - exit - fi - fi - fi -} - -exit-script() { - clear - echo -e "\n${CROSS}${RD}User exited script${CL}\n" - exit -} - -set_std_mode() { - if [ "$VERB" = "yes" ]; then - STD="" - else - STD="silent" - fi -} - -silent() { - if [ "$VERB" = "no" ]; then - "$@" >>"$LOGFILE" 2>&1 - else - "$@" 2>&1 | tee -a "$LOGFILE" - fi -} diff --git a/misc/backup_07052025/dialogue.bak b/misc/backup_07052025/dialogue.bak deleted file mode 100644 index 497b5fe0..00000000 --- a/misc/backup_07052025/dialogue.bak +++ /dev/null @@ -1,850 +0,0 @@ - -# dialog_input() { -# local title="$1" -# local prompt="$2" -# local default="$3" -# local result -# apt-get install -y dialog -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "$title" \ -# --extra-button --extra-label "Back" \ -# --ok-label "Next" --cancel-label "Exit" \ -# --inputbox "$prompt" 10 58 "$default" 2>&1 >/dev/tty) - -# local exitcode=$? - -# case $exitcode in -# 0) -# REPLY_RESULT="$result" -# return 0 -# ;; # OK -# 3) return 2 ;; # Back -# *) return 1 ;; # Cancel/Exit -# esac -# } - -# advanced_settings() { -# local step=1 - -# while true; do -# case $step in -# 1) -# show_intro_messages && ((step++)) -# ;; -# 2) -# select_distribution -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 3) -# select_version -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 4) -# select_container_type -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 5) -# set_root_password -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 6) -# set_container_id -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 7) -# set_hostname -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 8) -# set_disk_size -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 9) -# set_cpu_cores -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 10) -# set_ram_size -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 11) -# set_bridge -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 12) -# set_ip_address -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 13) -# set_gateway -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 14) -# set_apt_cacher -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 15) -# toggle_ipv6 -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 16) -# set_mtu -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 17) -# set_dns_search_domain -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 18) -# set_dns_server -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 19) -# set_mac_address -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 20) -# set_vlan -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 21) -# set_tags -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 22) -# set_ssh_access -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 23) -# set_fuse -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 24) -# set_verbose -# result=$? -# [[ $result -eq 0 ]] && ((step++)) -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# 25) -# confirm_creation -# result=$? -# [[ $result -eq 0 ]] && break -# [[ $result -eq 2 && $step -gt 1 ]] && ((step--)) -# [[ $result -eq 1 ]] && return -# ;; -# esac -# done -# } - -# show_intro_messages() { -# dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "Instructional Tip" \ -# --msgbox "To make a selection, use the Spacebar." 8 58 || return 1 - -# dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "Default distribution for $APP" \ -# --msgbox "Default is: ${var_os} ${var_version}\n\nIf the default Linux distribution is not adhered to, script support will be discontinued." 10 58 || return 1 -# return 0 -# } - -# select_distribution() { -# [[ "$var_os" == "alpine" ]] && return 0 - -# local default result exitcode -# default="${var_os:-debian}" -# var_os="" - -# local debian_flag ubuntu_flag -# [[ "$default" == "debian" ]] && debian_flag="on" || debian_flag="off" -# [[ "$default" == "ubuntu" ]] && ubuntu_flag="on" || ubuntu_flag="off" - -# while [[ -z "$var_os" ]]; do -# exec 3>&1 -# result=$(dialog --clear \ -# --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "DISTRIBUTION" \ -# --radiolist "Choose Distribution:" 15 60 4 \ -# "debian" "" "$debian_flag" \ -# "ubuntu" "" "$ubuntu_flag" \ -# --ok-label "Next" \ -# --cancel-label "Exit" \ -# --extra-button \ -# --extra-label "Back" \ -# 2>&1 1>&3) -# exitcode=$? -# exec 3>&- - -# case "$exitcode" in -# 0) -# if [[ "$result" =~ ^(debian|ubuntu)$ ]]; then -# var_os="$result" -# printf "%bOperating System: %b%s%b\n" "$OS$BOLD$DGN" "$BGN" "$var_os" "$CL" -# return 0 -# else -# printf "[DEBUG] No valid selection made (result='%s'), repeating...\n" "$result" -# fi -# ;; -# 3) -# return 2 -# ;; -# 1 | 255) -# return 1 -# ;; -# *) -# printf "[DEBUG] Unexpected exit code: %s\n" "$exitcode" >&2 -# return 1 -# ;; -# esac -# done -# } - -# select_version() { -# local default="${var_version}" -# var_version="" -# local list result exitcode - -# if [[ "$var_os" == "debian" ]]; then -# case "$default" in -# 11) list=("11" "Bullseye" on "12" "Bookworm" off) ;; -# 12) list=("11" "Bullseye" off "12" "Bookworm" on) ;; -# *) list=("11" "Bullseye" off "12" "Bookworm" off) ;; -# esac -# elif [[ "$var_os" == "ubuntu" ]]; then -# case "$default" in -# 20.04) list=("20.04" "Focal" on "22.04" "Jammy" off "24.04" "Noble" off "24.10" "Oracular" off) ;; -# 22.04) list=("20.04" "Focal" off "22.04" "Jammy" on "24.04" "Noble" off "24.10" "Oracular" off) ;; -# 24.04) list=("20.04" "Focal" off "22.04" "Jammy" off "24.04" "Noble" on "24.10" "Oracular" off) ;; -# 24.10) list=("20.04" "Focal" off "22.04" "Jammy" off "24.04" "Noble" off "24.10" "Oracular" on) ;; -# *) list=("20.04" "Focal" off "22.04" "Jammy" off "24.04" "Noble" off "24.10" "Oracular" off) ;; -# esac -# fi - -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "VERSION" \ -# --radiolist "Choose Version:" 15 58 5 \ -# "${list[@]}" \ -# --ok-label "Next" \ -# --cancel-label "Exit" \ -# --extra-button --extra-label "Back" \ -# 3>&1 1>&2 2>&3) - -# exitcode=$? - -# case $exitcode in -# 0) -# var_version="$result" -# printf "%bVersion: %b%s%b\n" "$OSVERSION$BOLD$DGN" "$BGN" "$var_version" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } - -# select_container_type() { -# local default="${CT_TYPE}" -# CT_TYPE="" -# local list result exitcode - -# [[ "$default" == "1" ]] && list=("1" "Unprivileged" on "0" "Privileged" off) || list=("1" "Unprivileged" off "0" "Privileged" on) - -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "CONTAINER TYPE" \ -# --radiolist "Choose Type:" 10 58 2 "${list[@]}" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) - -# exitcode=$? - -# case $exitcode in -# 0) -# CT_TYPE="$result" -# [[ "$CT_TYPE" == "0" ]] && desc="Privileged" || desc="Unprivileged" -# printf "%bContainer Type: %b%s%b\n" "$CONTAINERTYPE$BOLD$DGN" "$BGN" "$desc" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } -# set_root_password() { -# local pw1 pw2 exitcode - -# while true; do -# pw1=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "PASSWORD (leave blank for automatic login)" \ -# --insecure --passwordbox "\nSet Root Password (needed for root ssh access)" 10 58 \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# if [[ -z "$pw1" ]]; then -# PW1="Automatic Login" -# PW="" -# printf "%bRoot Password: %b%s%b\n" "$VERIFYPW$BOLD$DGN" "$BGN" "$PW1" "$CL" -# return 0 -# fi -# if [[ "$pw1" == *" "* ]]; then -# dialog --msgbox "Password cannot contain spaces. Please try again." 8 58 -# continue -# fi -# if [[ ${#pw1} -lt 5 ]]; then -# dialog --msgbox "Password must be at least 5 characters long. Please try again." 8 58 -# continue -# fi -# pw2=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "PASSWORD VERIFICATION" \ -# --insecure --passwordbox "\nVerify Root Password" 10 58 \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? -# case $exitcode in -# 0) -# if [[ "$pw1" == "$pw2" ]]; then -# PW="-password $pw1" -# printf "%bRoot Password: %b********%b\n" "$VERIFYPW$BOLD$DGN" "$BGN" "$CL" -# return 0 -# else -# dialog --msgbox "Passwords do not match. Please try again." 8 58 -# continue -# fi -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# done -# } - -# set_container_id() { -# local result exitcode -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "CONTAINER ID" \ -# --inputbox "Set Container ID" 8 58 "$NEXTID" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# CT_ID="${result:-$NEXTID}" -# printf "%bContainer ID: %b%s%b\n" "$CONTAINERID$BOLD$DGN" "$BGN" "$CT_ID" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } - -# set_hostname() { -# local result exitcode -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "HOSTNAME" \ -# --inputbox "Set Hostname" 8 58 "$NSAPP" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# if [[ -z "$result" ]]; then -# HN="$NSAPP" -# else -# HN=$(tr -d ' ' <<<"${result,,}") -# fi -# printf "%bHostname: %b%s%b\n" "$HOSTNAME$BOLD$DGN" "$BGN" "$HN" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } - -# set_disk_size() { -# local result exitcode -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "DISK SIZE" \ -# --inputbox "Set Disk Size in GB" 8 58 "$var_disk" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# if [[ -z "$result" ]]; then -# DISK_SIZE="$var_disk" -# elif [[ "$result" =~ ^[0-9]+$ ]]; then -# DISK_SIZE="$result" -# else -# dialog --msgbox "Disk size must be an integer!" 8 58 -# return 2 -# fi -# printf "%bDisk Size: %b%s GB%b\n" "$DISKSIZE$BOLD$DGN" "$BGN" "$DISK_SIZE" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } - -# set_cpu_cores() { -# local result exitcode -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "CORE COUNT" \ -# --inputbox "Allocate CPU Cores" 8 58 "$var_cpu" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# CORE_COUNT="${result:-$var_cpu}" -# printf "%bCPU Cores: %b%s%b\n" "$CPUCORE$BOLD$DGN" "$BGN" "$CORE_COUNT" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } - -# set_ram_size() { -# local result exitcode -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "RAM" \ -# --inputbox "Allocate RAM in MiB" 8 58 "$var_ram" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# RAM_SIZE="${result:-$var_ram}" -# printf "%bRAM Size: %b%s MiB%b\n" "$RAMSIZE$BOLD$DGN" "$BGN" "$RAM_SIZE" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } - -# set_bridge() { -# local result exitcode -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "BRIDGE" \ -# --inputbox "Set a Bridge" 8 58 "vmbr0" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# BRG="${result:-vmbr0}" -# printf "%bBridge: %b%s%b\n" "$BRIDGE$BOLD$DGN" "$BGN" "$BRG" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } - -# set_ip_address() { -# local result exitcode -# while true; do -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "IP ADDRESS" \ -# --inputbox "Set a Static IPv4 CIDR Address (/24)" 8 58 "dhcp" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# if [[ "$result" == "dhcp" ]]; then -# NET="dhcp" -# printf "%bIP Address: %b%s%b\n" "$NETWORK$BOLD$DGN" "$BGN" "$NET" "$CL" -# return 0 -# elif [[ "$result" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then -# NET="$result" -# printf "%bIP Address: %b%s%b\n" "$NETWORK$BOLD$DGN" "$BGN" "$NET" "$CL" -# return 0 -# else -# dialog --msgbox "$result is an invalid IPv4 CIDR address. Please enter a valid address or 'dhcp'." 8 58 -# continue -# fi -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# done -# } - -# set_gateway() { -# local result exitcode -# if [[ "$NET" == "dhcp" ]]; then -# GATE="" -# printf "%bGateway IP Address: %bDefault%b\n" "$GATEWAY$BOLD$DGN" "$BGN" "$CL" -# return 0 -# fi - -# while true; do -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "Gateway IP" \ -# --inputbox "Enter gateway IP address" 8 58 \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# if [[ -z "$result" ]]; then -# dialog --msgbox "Gateway IP address cannot be empty" 8 58 -# continue -# elif [[ "$result" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then -# GATE=",gw=$result" -# printf "%bGateway IP Address: %b%s%b\n" "$GATEWAY$BOLD$DGN" "$BGN" "$result" "$CL" -# return 0 -# else -# dialog --msgbox "Invalid IP address format" 8 58 -# fi -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# done -# } - -# set_apt_cacher() { -# local result exitcode -# if [[ "$var_os" == "alpine" ]]; then -# APT_CACHER="" -# APT_CACHER_IP="" -# return 0 -# fi - -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "APT-Cacher IP" \ -# --inputbox "Set APT-Cacher IP (leave blank for none)" 8 58 \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# APT_CACHER_IP="$result" -# APT_CACHER="${APT_CACHER_IP:+yes}" -# printf "%bAPT-Cacher IP Address: %b%s%b\n" "$NETWORK$BOLD$DGN" "$BGN" "${APT_CACHER_IP:-Default}" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } - -# toggle_ipv6() { -# dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "IPv6" \ -# --yesno "Disable IPv6?" 10 58 \ -# --extra-button --extra-label "Back" --ok-label "Yes" --cancel-label "No" -# case $? in -# 0) DISABLEIP6="yes" ;; -# 1) DISABLEIP6="no" ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# printf "%bDisable IPv6: %b%s%b\n" "$DISABLEIPV6$BOLD$DGN" "$BGN" "$DISABLEIP6" "$CL" -# return 0 -# } -# set_mtu() { -# local result exitcode -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "MTU SIZE" \ -# --inputbox "Set Interface MTU Size (leave blank for default [1500])" 8 58 "" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# if [[ -z "$result" ]]; then -# MTU1="Default" -# MTU="" -# else -# MTU1="$result" -# MTU=",mtu=$MTU1" -# fi -# printf "%bInterface MTU Size: %b%s%b\n" "$DEFAULT$BOLD$DGN" "$BGN" "$MTU1" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } - -# set_dns_search_domain() { -# local result exitcode -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "DNS Search Domain" \ -# --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 "" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# if [[ -z "$result" ]]; then -# SX="Host" -# SD="" -# else -# SX="$result" -# SD="-searchdomain=$result" -# fi -# printf "%bDNS Search Domain: %b%s%b\n" "$SEARCH$BOLD$DGN" "$BGN" "$SX" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } - -# set_dns_server() { -# local result exitcode -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "DNS SERVER IP" \ -# --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 "" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# if [[ -z "$result" ]]; then -# NX="Host" -# NS="" -# else -# NX="$result" -# NS="-nameserver=$result" -# fi -# printf "%bDNS Server IP Address: %b%s%b\n" "$NETWORK$BOLD$DGN" "$BGN" "$NX" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } - -# set_mac_address() { -# local result exitcode -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "MAC ADDRESS" \ -# --inputbox "Set a MAC Address (leave blank for generated MAC)" 8 58 "" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# if [[ -z "$result" ]]; then -# MAC1="Default" -# MAC="" -# else -# MAC1="$result" -# MAC=",hwaddr=$MAC1" -# fi -# printf "%bMAC Address: %b%s%b\n" "$MACADDRESS$BOLD$DGN" "$BGN" "$MAC1" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } - -# set_vlan() { -# local result exitcode -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "VLAN" \ -# --inputbox "Set a VLAN (leave blank for no VLAN)" 8 58 "" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# if [[ -z "$result" ]]; then -# VLAN1="Default" -# VLAN="" -# else -# VLAN1="$result" -# VLAN=",tag=$VLAN1" -# fi -# printf "%bVlan: %b%s%b\n" "$VLANTAG$BOLD$DGN" "$BGN" "$VLAN1" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } - -# set_tags() { -# local result exitcode -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "Advanced Tags" \ -# --inputbox "Set Custom Tags? [If you remove all, there will be no tags!]" 8 58 "$TAGS" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? - -# case $exitcode in -# 0) -# if [[ -n "$result" ]]; then -# ADV_TAGS=$(tr -d '[:space:]' <<<"$result") -# TAGS="$ADV_TAGS" -# else -# TAGS=";" -# fi -# printf "%bTags: %b%s%b\n" "$NETWORK$BOLD$DGN" "$BGN" "$TAGS" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } - -# set_ssh_access() { -# local result exitcode - -# if [[ "$PW" == -password* ]]; then -# dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "SSH ACCESS" \ -# --yesno "Enable Root SSH Access?" 10 58 \ -# --extra-button --extra-label "Back" --ok-label "Yes" --cancel-label "No" -# exitcode=$? -# case $exitcode in -# 0) SSH="yes" ;; -# 1) SSH="no" ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# else -# SSH="no" -# fi - -# printf "%bRoot SSH Access: %b%s%b\n" "$ROOTSSH$BOLD$DGN" "$BGN" "$SSH" "$CL" - -# if [[ "$SSH" == "yes" ]]; then -# result=$(dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "SSH Key" \ -# --inputbox "SSH Authorized key for root (leave empty for none)" 8 58 "" \ -# --extra-button --extra-label "Back" --ok-label "Next" --cancel-label "Exit" 3>&1 1>&2 2>&3) -# exitcode=$? -# case $exitcode in -# 0) -# SSH_AUTHORIZED_KEY="$result" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# else -# SSH_AUTHORIZED_KEY="" -# return 0 -# fi -# } - -# set_fuse() { -# dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "FUSE Support" \ -# --yesno "Enable FUSE (Filesystem in Userspace) support in the container?" 10 58 \ -# --extra-button --extra-label "Back" --ok-label "Yes" --cancel-label "No" -# case $? in -# 0) ENABLE_FUSE="yes" ;; -# 1) ENABLE_FUSE="no" ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# printf "%bFUSE (Filesystem in Userspace) Support: %b%s%b\n" "$FUSE$BOLD$DGN" "$BGN" "$ENABLE_FUSE" "$CL" -# return 0 -# } - -# set_verbose() { -# dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "VERBOSE MODE" \ -# --yesno "Enable Verbose Mode?" 10 58 \ -# --extra-button --extra-label "Back" --ok-label "Yes" --cancel-label "No" -# case $? in -# 0) VERB="yes" ;; -# 1) VERB="no" ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# printf "%bVerbose Mode: %b%s%b\n" "$SEARCH$BOLD$DGN" "$BGN" "$VERB" "$CL" -# return 0 -# } - -# confirm_creation() { -# dialog --backtitle "[dev] Proxmox VE Helper Scripts" \ -# --title "ADVANCED SETTINGS COMPLETE" \ -# --yesno "Ready to create ${APP} LXC?" 10 58 \ -# --extra-button --extra-label "Back" --ok-label "Yes" --cancel-label "No" -# case $? in -# 0) -# printf "%bCreating a %s LXC using the above advanced settings%b\n" "$CREATING$BOLD$RD" "$APP" "$CL" -# return 0 -# ;; -# 3) return 2 ;; -# *) return 1 ;; -# esac -# } diff --git a/misc/backup_07052025/install copy.func b/misc/backup_07052025/install copy.func deleted file mode 100644 index d2042d5d..00000000 --- a/misc/backup_07052025/install copy.func +++ /dev/null @@ -1,281 +0,0 @@ -# Copyright (c) 2021-2025 tteck -# Author: tteck (tteckster) -# Co-Author: MickLesk -# Co-Author: michelroegl-brunner -# License: MIT -# https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE - -source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) -load_functions - -# color() { -# # Colors -# YW=$(echo "\033[33m") -# YWB=$(echo "\033[93m") -# BL=$(echo "\033[36m") -# RD=$(echo "\033[01;31m") -# GN=$(echo "\033[1;92m") - -# # Formatting -# CL=$(echo "\033[m") -# BFR="\\r\\033[K" -# BOLD=$(echo "\033[1m") -# HOLD=" " -# TAB=" " - -# # System -# RETRY_NUM=10 -# RETRY_EVERY=3 - -# # Icons -# CM="${TAB}✔️${TAB}${CL}" -# CROSS="${TAB}✖️${TAB}${CL}" -# INFO="${TAB}💡${TAB}${CL}" -# NETWORK="${TAB}📡${TAB}${CL}" -# OS="${TAB}🖥️${TAB}${CL}" -# OSVERSION="${TAB}🌟${TAB}${CL}" -# HOSTNAME="${TAB}🏠${TAB}${CL}" -# GATEWAY="${TAB}🌐${TAB}${CL}" -# DEFAULT="${TAB}⚙️${TAB}${CL}" -# } - -# Function to set STD mode based on verbosity -set_std_mode() { - if [ "$VERBOSE" = "yes" ]; then - STD="" - else - STD="silent" - fi -} - -# Silent execution function -silent() { - "$@" >/dev/null 2>&1 -} - -# This function enables IPv6 if it's not disabled and sets verbose mode -verb_ip6() { - set_std_mode # Set STD mode based on VERBOSE - - if [ "$DISABLEIPV6" == "yes" ]; then - echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf - $STD sysctl -p - fi -} - -# This function sets error handling options and defines the error_handler function to handle errors -catch_errors() { - set -Eeuo pipefail - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -} - -# This function handles errors -error_handler() { - source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) - if [ -n "$SPINNER_PID" ] && ps -p "$SPINNER_PID" >/dev/null; then kill "$SPINNER_PID" >/dev/null; fi - printf "\e[?25h" - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message" - [[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" &>/dev/null || true - - if [[ "$line_number" -eq 50 ]]; then - echo -e "The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\n" - post_update_to_api "failed" "No error message, script ran in silent mode" - else - post_update_to_api "failed" "${command}" - fi -} - -# # This function displays a spinner. -# spinner() { -# local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏') -# local spin_i=0 -# local interval=0.1 -# printf "\e[?25l" - -# local color="${YWB}" - -# while true; do -# printf "\r ${color}%s${CL}" "${frames[spin_i]}" -# spin_i=$(((spin_i + 1) % ${#frames[@]})) -# sleep "$interval" -# done -# } - -# # This function displays an informational message with a yellow color. -# msg_info() { -# local msg="$1" -# echo -ne "${TAB}${YW}${HOLD}${msg}${HOLD}" -# spinner & -# SPINNER_PID=$! -# } - -# # This function displays a success message with a green color. -# msg_ok() { -# if [ -n "$SPINNER_PID" ] && ps -p "$SPINNER_PID" >/dev/null; then kill "$SPINNER_PID" >/dev/null; fi -# printf "\e[?25h" -# local msg="$1" -# echo -e "${BFR}${CM}${GN}${msg}${CL}" -# } - -# # This function displays a error message with a red color. -# msg_error() { -# if [ -n "$SPINNER_PID" ] && ps -p "$SPINNER_PID" >/dev/null; then kill "$SPINNER_PID" >/dev/null; fi -# printf "\e[?25h" -# local msg="$1" -# echo -e "${BFR}${CROSS}${RD}${msg}${CL}" -# } - -# This function sets up the Container OS by generating the locale, setting the timezone, and checking the network connection -setting_up_container() { - msg_info "Setting up Container OS" - sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen - locale_line=$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print $1}' | head -n 1) - echo "LANG=${locale_line}" >/etc/default/locale - locale-gen >/dev/null - export LANG=${locale_line} - echo $tz >/etc/timezone - ln -sf /usr/share/zoneinfo/$tz /etc/localtime - for ((i = RETRY_NUM; i > 0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - done - if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e "${NETWORK}Check Network Settings" - exit 1 - fi - rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED - systemctl disable -q --now systemd-networkd-wait-online.service - msg_ok "Set up Container OS" - msg_ok "Network Connected: ${BL}$(hostname -I)" -} - -# This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected -network_check() { - set +e - trap - ERR - ipv4_connected=false - ipv6_connected=false - sleep 1 - # Check IPv4 connectivity to Google, Cloudflare & Quad9 DNS servers. - if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then - msg_ok "IPv4 Internet Connected" - ipv4_connected=true - else - msg_error "IPv4 Internet Not Connected" - fi - - # Check IPv6 connectivity to Google, Cloudflare & Quad9 DNS servers. - if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null || ping6 -c 1 -W 1 2001:4860:4860::8888 &>/dev/null || ping6 -c 1 -W 1 2620:fe::fe &>/dev/null; then - msg_ok "IPv6 Internet Connected" - ipv6_connected=true - else - msg_error "IPv6 Internet Not Connected" - fi - - # If both IPv4 and IPv6 checks fail, prompt the user - if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then - read -r -p "No Internet detected,would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e "${INFO}${RD}Expect Issues Without Internet${CL}" - else - echo -e "${NETWORK}Check Network Settings" - exit 1 - fi - fi - - RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') - if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi - set -e - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -} - -# This function updates the Container OS by running apt-get update and upgrade -update_os() { - msg_info "Updating Container OS" - if [[ "$CACHER" == "yes" ]]; then - echo "Acquire::http::Proxy-Auto-Detect \"/usr/local/bin/apt-proxy-detect.sh\";" >/etc/apt/apt.conf.d/00aptproxy - cat </usr/local/bin/apt-proxy-detect.sh -#!/bin/bash -if nc -w1 -z "${CACHER_IP}" 3142; then - echo -n "http://${CACHER_IP}:3142" -else - echo -n "DIRECT" -fi -EOF - chmod +x /usr/local/bin/apt-proxy-detect.sh - fi - $STD apt-get update - $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade - rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED - msg_ok "Updated Container OS" - - msg_info "Installing core dependencies" - $STD apt-get update - $STD apt-get install -y sudo curl mc gnupg2 - msg_ok "Core dependencies installed" - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) - -} - -# This function modifies the message of the day (motd) and SSH settings -motd_ssh() { - grep -qxF "export TERM='xterm-256color'" /root/.bashrc || echo "export TERM='xterm-256color'" >>/root/.bashrc - - if [ -f "/etc/os-release" ]; then - OS_NAME=$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '"') - OS_VERSION=$(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"') - elif [ -f "/etc/debian_version" ]; then - OS_NAME="Debian" - OS_VERSION=$(cat /etc/debian_version) - fi - - PROFILE_FILE="/etc/profile.d/00_lxc-details.sh" - echo "echo -e \"\"" >"$PROFILE_FILE" - echo -e "echo -e \"${BOLD}${YW}${APPLICATION} LXC Container - DEV Repository${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${RD}WARNING: This is a DEVELOPMENT version (ProxmoxVED). Do NOT use in production!${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} IP Address: ${GN}\$(hostname -I | awk '{print \$1}')${CL}\"" >>"$PROFILE_FILE" - echo -e "echo -e \"${YW} Repository: ${GN}https://github.com/community-scripts/ProxmoxVED${CL}\"" >>"$PROFILE_FILE" - echo "echo \"\"" >>"$PROFILE_FILE" - - chmod -x /etc/update-motd.d/* - - if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd - fi -} - -# This function customizes the container by modifying the getty service and enabling auto-login for the root user -customize() { - if [[ "$PASSWORD" == "" ]]; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE - [Service] - ExecStart= - ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" - fi - echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update - chmod +x /usr/bin/update - if [[ -n "${SSH_AUTHORIZED_KEY}" ]]; then - mkdir -p /root/.ssh - echo "${SSH_AUTHORIZED_KEY}" >/root/.ssh/authorized_keys - chmod 700 /root/.ssh - chmod 600 /root/.ssh/authorized_keys - fi -} diff --git a/misc/backup_07052025/msg.func b/misc/backup_07052025/msg.func deleted file mode 100644 index 1257d0d2..00000000 --- a/misc/backup_07052025/msg.func +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env bash - -# Spinner state -declare -A SPINNER_PIDS -declare -A SPINNER_MSGS -declare -A MSG_SHOWN - -# Color definitions (adjust as needed) -RD='\033[0;31m' -GN='\033[0;32m' -YW='\033[0;33m' -CL='\033[0m' -CM='✔' -CROSS='✘' - -# Trap cleanup -trap cleanup_spinners EXIT INT TERM HUP - -# Hash function for message ID -msg_hash() { - local input="$1" - echo -n "$input" | sha1sum | awk '{print $1}' -} - -# Start a spinner for a specific message -start_spinner_for_msg() { - local msg="$1" - local id - id=$(msg_hash "$msg") - - [[ -n "${MSG_SHOWN["$id"]+x}" ]] && return - MSG_SHOWN["$id"]=1 - SPINNER_MSGS["$id"]="$msg" - - local frames=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏) - local interval=0.1 - local spin_i=0 - - { - while true; do - printf "\r\e[2K%s %b" "${frames[spin_i]}" "${YW}${msg}${CL}" >&2 - spin_i=$(((spin_i + 1) % ${#frames[@]})) - sleep "$interval" - done - } & - - SPINNER_PIDS["$id"]=$! - disown "${SPINNER_PIDS["$id"]}" -} - -# Stop the spinner for a specific message -stop_spinner_for_msg() { - local msg="$1" - local id - id=$(msg_hash "$msg") - - if [[ -n "${SPINNER_PIDS["$id"]+x}" ]] && ps -p "${SPINNER_PIDS["$id"]}" >/dev/null 2>&1; then - kill "${SPINNER_PIDS["$id"]}" 2>/dev/null - wait "${SPINNER_PIDS["$id"]}" 2>/dev/null || true - fi - - unset SPINNER_PIDS["$id"] - unset SPINNER_MSGS["$id"] - unset MSG_SHOWN["$id"] -} - -# Cleanup all active spinners -cleanup_spinners() { - for id in "${!SPINNER_PIDS[@]}"; do - if ps -p "${SPINNER_PIDS[$id]}" >/dev/null 2>&1; then - kill "${SPINNER_PIDS[$id]}" 2>/dev/null - wait "${SPINNER_PIDS[$id]}" 2>/dev/null || true - fi - unset SPINNER_PIDS["$id"] - unset SPINNER_MSGS["$id"] - unset MSG_SHOWN["$id"] - done -} - -# Show info message with spinner -msg_info() { - local msg="$1" - start_spinner_for_msg "$msg" -} - -# End spinner and show success message -msg_ok() { - local msg="$1" - stop_spinner_for_msg "$msg" - printf "\r\e[2K%s %b\n" "${CM}" "${GN}${msg}${CL}" >&2 -} - -# End spinner and show error message -msg_error() { - local msg="$1" - stop_spinner_for_msg "$msg" - printf "\r\e[2K%s %b\n" "${CROSS}" "${RD}${msg}${CL}" >&2 -} From 1617f334d58af43f8b3ac2e39a7ac34c3c53c807 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 12:11:08 +0200 Subject: [PATCH 389/463] Create add-iptag.sh --- tools/pve/add-iptag.sh | 1359 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1359 insertions(+) create mode 100644 tools/pve/add-iptag.sh diff --git a/tools/pve/add-iptag.sh b/tools/pve/add-iptag.sh new file mode 100644 index 00000000..49bf1a90 --- /dev/null +++ b/tools/pve/add-iptag.sh @@ -0,0 +1,1359 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (Canbiz) && Desert_Gamer +# License: MIT + +function header_info { + clear + cat <<"EOF" + ___ ____ _____ +|_ _| _ \ _ |_ _|_ _ __ _ + | || |_) (_) | |/ _` |/ _` | + | || __/ _ | | (_| | (_| | +|___|_| (_) |_|\__,_|\__, | + |___/ +EOF +} + +clear +header_info +APP="IP-Tag" +hostname=$(hostname) + +# Color variables +YW=$(echo "\033[33m") +GN=$(echo "\033[1;92m") +RD=$(echo "\033[01;31m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD=" " +CM=" ✔️ ${CL}" +CROSS=" ✖️ ${CL}" + +# Error handler for displaying error messages +error_handler() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then + kill $SPINNER_PID >/dev/null + fi + printf "\e[?25h" + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +# Spinner for progress indication +spinner() { + local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏') + local spin_i=0 + local interval=0.1 + printf "\e[?25l" + + local color="${YWB}" + + while true; do + printf "\r ${color}%s${CL}" "${frames[spin_i]}" + spin_i=$(((spin_i + 1) % ${#frames[@]})) + sleep "$interval" + done +} + +# Info message +msg_info() { + local msg="$1" + echo -ne "${TAB}${YW}${HOLD}${msg}${HOLD}" + spinner & + SPINNER_PID=$! +} + +# Success message +msg_ok() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then + kill $SPINNER_PID >/dev/null + fi + printf "\e[?25h" + local msg="$1" + echo -e "${BFR}${CM}${GN}${msg}${CL}" +} + +# Error message +msg_error() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then + kill $SPINNER_PID >/dev/null + fi + printf "\e[?25h" + local msg="$1" + echo -e "${BFR}${CROSS}${RD}${msg}${CL}" +} + +# Check if service exists +check_service_exists() { + if systemctl is-active --quiet iptag.service; then + return 0 + else + return 1 + fi +} + +# Migrate configuration from old path to new +migrate_config() { + local old_config="/opt/lxc-iptag" + local new_config="/opt/iptag/iptag.conf" + + if [[ -f "$old_config" ]]; then + msg_info "Migrating configuration from old path" + if cp "$old_config" "$new_config" &>/dev/null; then + rm -rf "$old_config" &>/dev/null + msg_ok "Configuration migrated and old config removed" + else + msg_error "Failed to migrate configuration" + fi + fi +} + +# Update existing installation +update_installation() { + msg_info "Updating IP-Tag Scripts" + systemctl stop iptag.service &>/dev/null + msg_ok "Stopped IP-Tag service" + + # Create directory if it doesn't exist + if [[ ! -d "/opt/iptag" ]]; then + mkdir -p /opt/iptag + fi + + # Create new config file (check if exists and ask user) + if [[ -f "/opt/iptag/iptag.conf" ]]; then + echo -e "\n${YW}Configuration file already exists.${CL}" + while true; do + read -p "Do you want to replace it with defaults? (y/n): " yn + case $yn in + [Yy]*) + msg_info "Replacing configuration file" + generate_config >/opt/iptag/iptag.conf + msg_ok "Configuration file replaced with defaults" + break + ;; + [Nn]*) + echo -e "${GN}✔️ Keeping existing configuration file${CL}" + break + ;; + *) + echo -e "${RD}Please answer yes or no.${CL}" + ;; + esac + done + else + msg_info "Creating new configuration file" + generate_config >/opt/iptag/iptag.conf + msg_ok "Created new configuration file at /opt/iptag/iptag.conf" + fi + + # Update main script + msg_info "Updating main script" + generate_main_script >/opt/iptag/iptag + chmod +x /opt/iptag/iptag + msg_ok "Updated main script" + + # Update service file + msg_info "Updating service file" + generate_service >/lib/systemd/system/iptag.service + msg_ok "Updated service file" + + msg_info "Creating manual run command" + cat <<'EOF' >/usr/local/bin/iptag-run +#!/usr/bin/env bash +CONFIG_FILE="/opt/iptag/iptag.conf" +SCRIPT_FILE="/opt/iptag/iptag" +if [[ ! -f "$SCRIPT_FILE" ]]; then + echo "❌ Main script not found: $SCRIPT_FILE" + exit 1 +fi +export FORCE_SINGLE_RUN=true +exec "$SCRIPT_FILE" +EOF + chmod +x /usr/local/bin/iptag-run + msg_ok "Created iptag-run executable - You can execute this manually by entering “iptag-run” in the Proxmox host, so the script is executed by hand." + + msg_info "Restarting service" + systemctl daemon-reload &>/dev/null + systemctl enable -q --now iptag.service &>/dev/null + msg_ok "Updated IP-Tag Scripts" +} + +# Generate configuration file content +generate_config() { + cat <&2 + fi +} + +# Color constants +readonly RED='\033[0;31m' +readonly GREEN='\033[0;32m' +readonly YELLOW='\033[0;33m' +readonly BLUE='\033[0;34m' +readonly PURPLE='\033[0;35m' +readonly CYAN='\033[0;36m' +readonly WHITE='\033[1;37m' +readonly GRAY='\033[0;37m' +readonly NC='\033[0m' # No Color + +# Logging functions with colors +log_success() { + echo -e "${GREEN}✓${NC} $*" +} + +log_info() { + echo -e "${BLUE}ℹ${NC} $*" +} + +log_warning() { + echo -e "${YELLOW}⚠${NC} $*" +} + +log_error() { + echo -e "${RED}✗${NC} $*" +} + +log_change() { + echo -e "${CYAN}~${NC} $*" +} + +log_unchanged() { + echo -e "${GRAY}=${NC} $*" +} + +# Check if IP is in CIDR +ip_in_cidr() { + local ip="$1" cidr="$2" + debug_log "ip_in_cidr: checking '$ip' against '$cidr'" + + # Manual CIDR check - более надёжный метод + debug_log "ip_in_cidr: using manual check (bypassing ipcalc)" + local network prefix + IFS='/' read -r network prefix <<< "$cidr" + + # Convert IP and network to integers for comparison + local ip_int net_int mask + IFS='.' read -r a b c d <<< "$ip" + ip_int=$(( (a << 24) + (b << 16) + (c << 8) + d )) + + IFS='.' read -r a b c d <<< "$network" + net_int=$(( (a << 24) + (b << 16) + (c << 8) + d )) + + # Create subnet mask + mask=$(( 0xFFFFFFFF << (32 - prefix) )) + + # Apply mask and compare + local ip_masked=$((ip_int & mask)) + local net_masked=$((net_int & mask)) + + debug_log "ip_in_cidr: IP=$ip ($ip_int), Network=$network ($net_int), Prefix=$prefix" + debug_log "ip_in_cidr: Mask=$mask (hex: $(printf '0x%08x' $mask))" + debug_log "ip_in_cidr: IP&Mask=$ip_masked ($(printf '%d.%d.%d.%d' $((ip_masked>>24&255)) $((ip_masked>>16&255)) $((ip_masked>>8&255)) $((ip_masked&255))))" + debug_log "ip_in_cidr: Net&Mask=$net_masked ($(printf '%d.%d.%d.%d' $((net_masked>>24&255)) $((net_masked>>16&255)) $((net_masked>>8&255)) $((net_masked&255))))" + + if (( ip_masked == net_masked )); then + debug_log "ip_in_cidr: manual check PASSED - IP is in CIDR" + return 0 + else + debug_log "ip_in_cidr: manual check FAILED - IP is NOT in CIDR" + return 1 + fi +} + +# Format IP address according to the configuration +format_ip_tag() { + local ip="$1" + [[ -z "$ip" ]] && return + local format="${TAG_FORMAT:-$DEFAULT_TAG_FORMAT}" + case "$format" in + "last_octet") echo "${ip##*.}" ;; + "last_two_octets") echo "${ip#*.*.}" ;; + *) echo "$ip" ;; + esac +} + +# Check if IP is in any CIDRs +ip_in_cidrs() { + local ip="$1" cidrs="$2" + [[ -z "$cidrs" ]] && return 1 + local IFS=' ' + debug_log "Checking IP '$ip' against CIDRs: '$cidrs'" + for cidr in $cidrs; do + debug_log "Testing IP '$ip' against CIDR '$cidr'" + if ip_in_cidr "$ip" "$cidr"; then + debug_log "IP '$ip' matches CIDR '$cidr' - PASSED" + return 0 + else + debug_log "IP '$ip' does not match CIDR '$cidr'" + fi + done + debug_log "IP '$ip' failed all CIDR checks" + return 1 +} + +# Check if IP is valid +is_valid_ipv4() { + local ip="$1" + [[ "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] || return 1 + + local IFS='.' parts + read -ra parts <<< "$ip" + for part in "${parts[@]}"; do + (( part >= 0 && part <= 255 )) || return 1 + done + return 0 +} + +# Get VM IPs using multiple methods with performance optimizations +get_vm_ips() { + local vmid=$1 ips="" + local vm_config="/etc/pve/qemu-server/${vmid}.conf" + [[ ! -f "$vm_config" ]] && return + + debug_log "vm $vmid: starting optimized IP detection" + + # Check if VM is running first (avoid expensive operations for stopped VMs) + local vm_status="" + if command -v qm >/dev/null 2>&1; then + vm_status=$(qm status "$vmid" 2>/dev/null | awk '{print $2}') + fi + + if [[ "$vm_status" != "running" ]]; then + debug_log "vm $vmid: not running (status: $vm_status), skipping expensive detection" + return + fi + + # Cache for this execution + local cache_file="/tmp/iptag_vm_${vmid}_cache" + local cache_ttl=60 # 60 seconds cache + + # Check cache first + if [[ -f "$cache_file" ]] && [[ $(($(date +%s) - $(stat -c %Y "$cache_file" 2>/dev/null || echo 0))) -lt $cache_ttl ]]; then + local cached_ips=$(cat "$cache_file" 2>/dev/null) + if [[ -n "$cached_ips" ]]; then + debug_log "vm $vmid: using cached IPs: $cached_ips" + echo "$cached_ips" + return + fi + fi + + # Method 1: Quick ARP table lookup (fastest) + local mac_addresses=$(grep -E "^net[0-9]+:" "$vm_config" | grep -oE "([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}" | head -3) + debug_log "vm $vmid: found MACs: $mac_addresses" + + # Quick ARP check without forced refresh (most common case) + for mac in $mac_addresses; do + local mac_lower=$(echo "$mac" | tr '[:upper:]' '[:lower:]') + local ip=$(ip neighbor show | grep "$mac_lower" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1) + if [[ -n "$ip" && "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + debug_log "vm $vmid: found IP $ip via quick ARP for MAC $mac_lower" + ips+="$ip " + fi + done + + # Early exit if we found IPs via ARP + if [[ -n "$ips" ]]; then + local unique_ips=$(echo "$ips" | tr ' ' '\n' | sort -u | tr '\n' ' ') + unique_ips="${unique_ips% }" + debug_log "vm $vmid: early exit with IPs: '$unique_ips'" + echo "$unique_ips" > "$cache_file" + echo "$unique_ips" + return + fi + + # Method 2: QM guest agent (fast if available) + if command -v qm >/dev/null 2>&1; then + local qm_ips=$(timeout 3 qm guest cmd "$vmid" network-get-interfaces 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v "127.0.0.1" | head -2) + for qm_ip in $qm_ips; do + if [[ "$qm_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + debug_log "vm $vmid: found IP $qm_ip via qm guest cmd" + ips+="$qm_ip " + fi + done + fi + + # Early exit if we found IPs via QM + if [[ -n "$ips" ]]; then + local unique_ips=$(echo "$ips" | tr ' ' '\n' | sort -u | tr '\n' ' ') + unique_ips="${unique_ips% }" + debug_log "vm $vmid: early exit with QM IPs: '$unique_ips'" + echo "$unique_ips" > "$cache_file" + echo "$unique_ips" + return + fi + + # Method 3: DHCP leases check (medium cost) + for mac in $mac_addresses; do + local mac_lower=$(echo "$mac" | tr '[:upper:]' '[:lower:]') + + for dhcp_file in "/var/lib/dhcp/dhcpd.leases" "/var/lib/dhcpcd5/dhcpcd.leases" "/tmp/dhcp.leases"; do + if [[ -f "$dhcp_file" ]]; then + local dhcp_ip=$(timeout 2 grep -A 10 "ethernet $mac_lower" "$dhcp_file" 2>/dev/null | grep "binding state active" -A 5 | grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" | head -1) + if [[ -n "$dhcp_ip" && "$dhcp_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + debug_log "vm $vmid: found IP $dhcp_ip via DHCP leases for MAC $mac_lower" + ips+="$dhcp_ip " + break 2 + fi + fi + done + done + + # Early exit if we found IPs via DHCP + if [[ -n "$ips" ]]; then + local unique_ips=$(echo "$ips" | tr ' ' '\n' | sort -u | tr '\n' ' ') + unique_ips="${unique_ips% }" + debug_log "vm $vmid: early exit with DHCP IPs: '$unique_ips'" + echo "$unique_ips" > "$cache_file" + echo "$unique_ips" + return + fi + + # Method 4: Limited network discovery (expensive - only if really needed) + debug_log "vm $vmid: falling back to limited network discovery" + + for mac in $mac_addresses; do + local mac_lower=$(echo "$mac" | tr '[:upper:]' '[:lower:]') + + # Get bridge interfaces + local bridges=$(grep -E "^net[0-9]+:" "$vm_config" | grep -oE "bridge=\w+" | cut -d= -f2 | head -1) + for bridge in $bridges; do + if [[ -n "$bridge" && -d "/sys/class/net/$bridge" ]]; then + # Get bridge IP range + local bridge_ip=$(ip addr show "$bridge" 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+' | head -1) + if [[ -n "$bridge_ip" ]]; then + local network=$(echo "$bridge_ip" | cut -d'/' -f1) + debug_log "vm $vmid: limited scan on bridge $bridge network $bridge_ip" + + # Force ARP refresh with broadcast ping (limited) + IFS='.' read -r a b c d <<< "$network" + local broadcast="$a.$b.$c.255" + timeout 1 ping -c 1 -b "$broadcast" >/dev/null 2>&1 || true + + # Check ARP again after refresh + sleep 0.5 + local ip=$(ip neighbor show | grep "$mac_lower" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1) + if [[ -n "$ip" && "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + debug_log "vm $vmid: found IP $ip via ARP after broadcast for MAC $mac_lower" + ips+="$ip " + break 2 + fi + + # Only do very limited ping scan (reduced range) + IFS='.' read -r a b c d <<< "$network" + local base_net="$a.$b.$c" + + # Try only most common ranges (much smaller than before) + for last_octet in {100..105} {200..205}; do + local test_ip="$base_net.$last_octet" + + # Very quick ping test (reduced timeout) + if timeout 0.2 ping -c 1 -W 1 "$test_ip" >/dev/null 2>&1; then + # Check if this IP corresponds to our MAC + sleep 0.1 + local found_mac=$(ip neighbor show "$test_ip" 2>/dev/null | grep -oE "([0-9a-f]{2}:){5}[0-9a-f]{2}") + if [[ "$found_mac" == "$mac_lower" ]]; then + debug_log "vm $vmid: found IP $test_ip via limited ping scan for MAC $mac_lower" + ips+="$test_ip " + break 2 + fi + fi + done + + # Skip extended scanning entirely (too expensive) + debug_log "vm $vmid: skipping extended scan to preserve CPU" + fi + fi + done + done + + # Method 5: Static configuration check (fast) + if [[ -z "$ips" ]]; then + debug_log "vm $vmid: checking for static IP configuration" + + # Check cloud-init configuration if exists + local cloudinit_file="/var/lib/vz/snippets/${vmid}-cloud-init.yml" + if [[ -f "$cloudinit_file" ]]; then + local static_ip=$(grep -E "addresses?:" "$cloudinit_file" 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1) + if [[ -n "$static_ip" && "$static_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + debug_log "vm $vmid: found static IP $static_ip in cloud-init config" + ips+="$static_ip " + fi + fi + + # Check VM config for any IP hints + local config_ip=$(grep -E "(ip=|gw=)" "$vm_config" 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1) + if [[ -n "$config_ip" && "$config_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + debug_log "vm $vmid: found IP hint $config_ip in VM config" + ips+="$config_ip " + fi + fi + + # Remove duplicates and cache result + local unique_ips=$(echo "$ips" | tr ' ' '\n' | sort -u | tr '\n' ' ') + unique_ips="${unique_ips% }" + + # Cache the result (even if empty) + echo "$unique_ips" > "$cache_file" + + debug_log "vm $vmid: final optimized IPs: '$unique_ips'" + echo "$unique_ips" +} + +# Update tags for container or VM +update_tags() { + local type="$1" vmid="$2" + local current_ips_full + + if [[ "$type" == "lxc" ]]; then + current_ips_full=$(get_lxc_ips "${vmid}") + while IFS= read -r line; do + [[ "$line" == tags:* ]] && current_tags_raw="${line#tags: }" && break + done < <(pct config "$vmid" 2>/dev/null) + else + current_ips_full=$(get_vm_ips "${vmid}") + local vm_config="/etc/pve/qemu-server/${vmid}.conf" + if [[ -f "$vm_config" ]]; then + local current_tags_raw=$(grep "^tags:" "$vm_config" 2>/dev/null | cut -d: -f2 | sed 's/^[[:space:]]*//') + fi + fi + + local current_tags=() next_tags=() current_ip_tags=() + if [[ -n "$current_tags_raw" ]]; then + mapfile -t current_tags < <(echo "$current_tags_raw" | sed 's/;/\n/g') + fi + + # Separate IP/numeric and user tags + for tag in "${current_tags[@]}"; do + if is_valid_ipv4 "${tag}" || [[ "$tag" =~ ^[0-9]+(\.[0-9]+)*$ ]]; then + current_ip_tags+=("${tag}") + else + next_tags+=("${tag}") + fi + done + + # Generate new IP tags from current IPs + local formatted_ips=() + debug_log "$type $vmid current_ips_full: '$current_ips_full'" + debug_log "$type $vmid CIDR_LIST: ${CIDR_LIST[*]}" + for ip in $current_ips_full; do + [[ -z "$ip" ]] && continue + debug_log "$type $vmid processing IP: '$ip'" + if is_valid_ipv4 "$ip"; then + debug_log "$type $vmid IP '$ip' is valid" + if ip_in_cidrs "$ip" "${CIDR_LIST[*]}"; then + debug_log "$type $vmid IP '$ip' passed CIDR check" + local formatted_ip=$(format_ip_tag "$ip") + debug_log "$type $vmid formatted '$ip' -> '$formatted_ip'" + [[ -n "$formatted_ip" ]] && formatted_ips+=("$formatted_ip") + else + debug_log "$type $vmid IP '$ip' failed CIDR check" + fi + else + debug_log "$type $vmid IP '$ip' is invalid" + fi + done + debug_log "$type $vmid final formatted_ips: ${formatted_ips[*]}" + + # If LXC and no IPs detected, do not touch tags at all + if [[ "$type" == "lxc" && ${#formatted_ips[@]} -eq 0 ]]; then + log_unchanged "LXC ${GRAY}${vmid}${NC}: No IP detected, tags unchanged" + return + fi + + # Add new IP tags + for new_ip in "${formatted_ips[@]}"; do + next_tags+=("$new_ip") + done + + # Update tags if there are changes + local old_tags_str=$(IFS=';'; echo "${current_tags[*]}") + local new_tags_str=$(IFS=';'; echo "${next_tags[*]}") + + debug_log "$type $vmid old_tags: '$old_tags_str'" + debug_log "$type $vmid new_tags: '$new_tags_str'" + debug_log "$type $vmid tags_equal: $([[ "$old_tags_str" == "$new_tags_str" ]] && echo true || echo false)" + + if [[ "$old_tags_str" != "$new_tags_str" ]]; then + # Determine what changed + local old_ip_tags_count=${#current_ip_tags[@]} + local new_ip_tags_count=${#formatted_ips[@]} + + # Build detailed change message + local change_details="" + + if [[ $old_ip_tags_count -eq 0 ]]; then + change_details="added ${new_ip_tags_count} IP tag(s): [${GREEN}${formatted_ips[*]}${NC}]" + else + # Compare old and new IP tags + local added_tags=() removed_tags=() common_tags=() + + # Find removed tags + for old_tag in "${current_ip_tags[@]}"; do + local found=false + for new_tag in "${formatted_ips[@]}"; do + if [[ "$old_tag" == "$new_tag" ]]; then + found=true + break + fi + done + if [[ "$found" == false ]]; then + removed_tags+=("$old_tag") + else + common_tags+=("$old_tag") + fi + done + + # Find added tags + for new_tag in "${formatted_ips[@]}"; do + local found=false + for old_tag in "${current_ip_tags[@]}"; do + if [[ "$new_tag" == "$old_tag" ]]; then + found=true + break + fi + done + if [[ "$found" == false ]]; then + added_tags+=("$new_tag") + fi + done + + # Build change message + local change_parts=() + if [[ ${#added_tags[@]} -gt 0 ]]; then + change_parts+=("added [${GREEN}${added_tags[*]}${NC}]") + fi + if [[ ${#removed_tags[@]} -gt 0 ]]; then + change_parts+=("removed [${YELLOW}${removed_tags[*]}${NC}]") + fi + if [[ ${#common_tags[@]} -gt 0 ]]; then + change_parts+=("kept [${GRAY}${common_tags[*]}${NC}]") + fi + + change_details=$(IFS=', '; echo "${change_parts[*]}") + fi + + log_change "${type^^} ${CYAN}${vmid}${NC}: ${change_details}" + + if [[ "$type" == "lxc" ]]; then + pct set "${vmid}" -tags "$(IFS=';'; echo "${next_tags[*]}")" &>/dev/null + else + local vm_config="/etc/pve/qemu-server/${vmid}.conf" + if [[ -f "$vm_config" ]]; then + sed -i '/^tags:/d' "$vm_config" + if [[ ${#next_tags[@]} -gt 0 ]]; then + echo "tags: $(IFS=';'; echo "${next_tags[*]}")" >> "$vm_config" + fi + fi + fi + else + # Tags unchanged + local ip_count=${#formatted_ips[@]} + local status_msg="" + + if [[ $ip_count -eq 0 ]]; then + status_msg="No IPs detected" + elif [[ $ip_count -eq 1 ]]; then + status_msg="IP tag [${GRAY}${formatted_ips[0]}${NC}] unchanged" + else + status_msg="${ip_count} IP tags [${GRAY}${formatted_ips[*]}${NC}] unchanged" + fi + + log_unchanged "${type^^} ${GRAY}${vmid}${NC}: ${status_msg}" + fi +} + +# Update all instances of specified type +update_all_tags() { + local type="$1" vmids count=0 + + if [[ "$type" == "lxc" ]]; then + vmids=($(pct list 2>/dev/null | grep -v VMID | awk '{print $1}')) + else + local all_vm_configs=($(ls /etc/pve/qemu-server/*.conf 2>/dev/null | sed 's/.*\/\([0-9]*\)\.conf/\1/' | sort -n)) + vmids=("${all_vm_configs[@]}") + fi + + count=${#vmids[@]} + [[ $count -eq 0 ]] && return + + # Display processing header with color + if [[ "$type" == "lxc" ]]; then + log_info "Processing ${WHITE}${count}${NC} LXC container(s) in parallel" + + # Clean up old cache files before processing LXC + cleanup_vm_cache + + # Process LXC containers in parallel for better performance + process_lxc_parallel "${vmids[@]}" + else + log_info "Processing ${WHITE}${count}${NC} virtual machine(s) in parallel" + + # Clean up old cache files before processing VMs + cleanup_vm_cache + + # Process VMs in parallel for better performance + process_vms_parallel "${vmids[@]}" + fi + + # Add completion message + if [[ "$type" == "lxc" ]]; then + log_success "Completed processing LXC containers" + else + log_success "Completed processing virtual machines" + fi +} + +# Check if status changed +check_status_changed() { + local type="$1" current + case "$type" in + "lxc") current=$(pct list 2>/dev/null | grep -v VMID) ;; + "vm") current=$(ls -la /etc/pve/qemu-server/*.conf 2>/dev/null) ;; + "fw") current=$(ip link show type bridge 2>/dev/null) ;; + esac + local last_var="last_${type}_status" + [[ "${!last_var}" == "$current" ]] && return 1 + eval "$last_var='$current'" + return 0 +} + +# Main check function +check() { + local current_time changes_detected=false + current_time=$(date +%s) + + local update_lxc=false + local update_vm=false + + # Periodic cache cleanup (every 10 minutes) + local time_since_last_cleanup=$((current_time - ${last_cleanup_time:-0})) + if [[ $time_since_last_cleanup -ge 600 ]]; then + cleanup_vm_cache + last_cleanup_time=$current_time + debug_log "Performed periodic cache cleanup" + fi + + # Check LXC status + local time_since_last_lxc_check=$((current_time - last_lxc_status_check_time)) + if [[ "${LXC_STATUS_CHECK_INTERVAL:-60}" -gt 0 ]] && \ + [[ "$time_since_last_lxc_check" -ge "${LXC_STATUS_CHECK_INTERVAL:-60}" ]]; then + last_lxc_status_check_time=$current_time + if check_status_changed "lxc"; then + update_lxc=true + log_warning "LXC status changes detected" + fi + fi + + # Check VM status + local time_since_last_vm_check=$((current_time - last_vm_status_check_time)) + if [[ "${VM_STATUS_CHECK_INTERVAL:-60}" -gt 0 ]] && \ + [[ "$time_since_last_vm_check" -ge "${VM_STATUS_CHECK_INTERVAL:-60}" ]]; then + last_vm_status_check_time=$current_time + if check_status_changed "vm"; then + update_vm=true + log_warning "VM status changes detected" + fi + fi + + # Check network interface changes + local time_since_last_fw_check=$((current_time - last_fw_net_interface_check_time)) + if [[ "${FW_NET_INTERFACE_CHECK_INTERVAL:-60}" -gt 0 ]] && \ + [[ "$time_since_last_fw_check" -ge "${FW_NET_INTERFACE_CHECK_INTERVAL:-60}" ]]; then + last_fw_net_interface_check_time=$current_time + if check_status_changed "fw"; then + update_lxc=true + update_vm=true + log_warning "Network interface changes detected" + fi + fi + + # Force update if interval exceeded + for type in "lxc" "vm"; do + local last_update_var="last_update_${type}_time" + local time_since_last_update=$((current_time - ${!last_update_var})) + if [[ $time_since_last_update -ge ${FORCE_UPDATE_INTERVAL:-1800} ]]; then + if [[ "$type" == "lxc" ]]; then + update_lxc=true + log_info "Scheduled LXC update (every $((FORCE_UPDATE_INTERVAL / 60)) minutes)" + else + update_vm=true + log_info "Scheduled VM update (every $((FORCE_UPDATE_INTERVAL / 60)) minutes)" + fi + eval "${last_update_var}=${current_time}" + fi + done + + # Final execution + $update_lxc && update_all_tags "lxc" + $update_vm && update_all_tags "vm" +} + +# Initialize time variables +declare -g last_lxc_status="" last_vm_status="" last_fw_status="" +declare -g last_lxc_status_check_time=0 last_vm_status_check_time=0 last_fw_net_interface_check_time=0 +declare -g last_update_lxc_time=0 last_update_vm_time=0 last_cleanup_time=0 + +# Main loop +main() { + # Display startup message + echo -e "\n${PURPLE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" + log_success "IP-Tag service started successfully" + echo -e "${BLUE}ℹ${NC} Loop interval: ${WHITE}${LOOP_INTERVAL:-$DEFAULT_CHECK_INTERVAL}${NC} seconds" + echo -e "${BLUE}ℹ${NC} Debug mode: ${WHITE}${DEBUG:-false}${NC}" + echo -e "${BLUE}ℹ${NC} Tag format: ${WHITE}${TAG_FORMAT:-$DEFAULT_TAG_FORMAT}${NC}" + echo -e "${BLUE}ℹ${NC} Allowed CIDRs: ${WHITE}${CIDR_LIST[*]}${NC}" + echo -e "${PURPLE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n" + + if [[ "$FORCE_SINGLE_RUN" == "true" ]]; then + check + exit 0 + fi + + while true; do + check + sleep "${LOOP_INTERVAL:-300}" + done +} + + +# Cache cleanup function +cleanup_vm_cache() { + local cache_dir="/tmp" + local vm_cache_ttl=${VM_IP_CACHE_TTL:-120} + local lxc_cache_ttl=${LXC_IP_CACHE_TTL:-120} + local status_cache_ttl=${LXC_STATUS_CACHE_TTL:-30} + local current_time=$(date +%s) + + debug_log "Starting extreme cache cleanup" + + # Clean VM cache files + for cache_file in "$cache_dir"/iptag_vm_*_cache; do + if [[ -f "$cache_file" ]]; then + local file_time=$(stat -c %Y "$cache_file" 2>/dev/null || echo 0) + if [[ $((current_time - file_time)) -gt $vm_cache_ttl ]]; then + rm -f "$cache_file" 2>/dev/null + debug_log "Cleaned up expired VM cache file: $cache_file" + fi + fi + done + + # Clean LXC IP cache files + for cache_file in "$cache_dir"/iptag_lxc_*_cache; do + if [[ -f "$cache_file" ]]; then + local file_time=$(stat -c %Y "$cache_file" 2>/dev/null || echo 0) + if [[ $((current_time - file_time)) -gt $lxc_cache_ttl ]]; then + rm -f "$cache_file" 2>/dev/null + # Also clean meta files + rm -f "${cache_file}.meta" 2>/dev/null + debug_log "Cleaned up expired LXC cache file: $cache_file" + fi + fi + done + + # Clean LXC status cache files (shorter TTL) + for cache_file in "$cache_dir"/iptag_lxc_status_*_cache; do + if [[ -f "$cache_file" ]]; then + local file_time=$(stat -c %Y "$cache_file" 2>/dev/null || echo 0) + if [[ $((current_time - file_time)) -gt $status_cache_ttl ]]; then + rm -f "$cache_file" 2>/dev/null + debug_log "Cleaned up expired LXC status cache: $cache_file" + fi + fi + done + + # Clean LXC PID cache files (60 second TTL) + for cache_file in "$cache_dir"/iptag_lxc_pid_*_cache; do + if [[ -f "$cache_file" ]]; then + local file_time=$(stat -c %Y "$cache_file" 2>/dev/null || echo 0) + if [[ $((current_time - file_time)) -gt 60 ]]; then + rm -f "$cache_file" 2>/dev/null + debug_log "Cleaned up expired LXC PID cache: $cache_file" + fi + fi + done + + # Clean any orphaned meta files + for meta_file in "$cache_dir"/iptag_*.meta; do + if [[ -f "$meta_file" ]]; then + local base_file="${meta_file%.meta}" + if [[ ! -f "$base_file" ]]; then + rm -f "$meta_file" 2>/dev/null + debug_log "Cleaned up orphaned meta file: $meta_file" + fi + fi + done + + debug_log "Completed extreme cache cleanup" +} + +# Parallel VM processing function +process_vms_parallel() { + local vm_list=("$@") + local max_parallel=${MAX_PARALLEL_VM_CHECKS:-5} + local job_count=0 + local pids=() + local pid_start_times=() + + for vmid in "${vm_list[@]}"; do + if [[ $job_count -ge $max_parallel ]]; then + local pid_to_wait="${pids[0]}" + local start_time="${pid_start_times[0]}" + local waited=0 + while kill -0 "$pid_to_wait" 2>/dev/null && [[ $waited -lt 10 ]]; do + sleep 1 + ((waited++)) + done + if kill -0 "$pid_to_wait" 2>/dev/null; then + kill -9 "$pid_to_wait" 2>/dev/null + log_warning "VM parallel: killed stuck process $pid_to_wait after 10s timeout" + else + wait "$pid_to_wait" + fi + pids=("${pids[@]:1}") + pid_start_times=("${pid_start_times[@]:1}") + ((job_count--)) + fi + # Start background job + (update_tags "vm" "$vmid") & + pids+=($!) + pid_start_times+=("$(date +%s)") + ((job_count++)) + done + for i in "${!pids[@]}"; do + local pid="${pids[$i]}" + local waited=0 + while kill -0 "$pid" 2>/dev/null && [[ $waited -lt 10 ]]; do + sleep 1 + ((waited++)) + done + if kill -0 "$pid" 2>/dev/null; then + kill -9 "$pid" 2>/dev/null + log_warning "VM parallel: killed stuck process $pid after 10s timeout" + else + wait "$pid" + fi + done +} + +# Parallel LXC processing function +process_lxc_parallel() { + local lxc_list=("$@") + local max_parallel=${MAX_PARALLEL_LXC_CHECKS:-2} + local batch_size=${LXC_BATCH_SIZE:-20} + local job_count=0 + local pids=() + local pid_start_times=() + + debug_log "Starting parallel LXC processing: ${#lxc_list[@]} containers, max_parallel=$max_parallel" + + if [[ ${#lxc_list[@]} -gt 5 ]]; then + debug_log "Pre-loading LXC statuses for ${#lxc_list[@]} containers" + local all_statuses=$(pct list 2>/dev/null) + for vmid in "${lxc_list[@]}"; do + local status=$(echo "$all_statuses" | grep "^$vmid" | awk '{print $2}') + if [[ -n "$status" ]]; then + local status_cache_file="/tmp/iptag_lxc_status_${vmid}_cache" + echo "$status" > "$status_cache_file" 2>/dev/null & + fi + done + wait + debug_log "Completed batch status pre-loading" + fi + for vmid in "${lxc_list[@]}"; do + if [[ $job_count -ge $max_parallel ]]; then + local pid_to_wait="${pids[0]}" + local start_time="${pid_start_times[0]}" + local waited=0 + while kill -0 "$pid_to_wait" 2>/dev/null && [[ $waited -lt 10 ]]; do + sleep 1 + ((waited++)) + done + if kill -0 "$pid_to_wait" 2>/dev/null; then + kill -9 "$pid_to_wait" 2>/dev/null + log_warning "LXC parallel: killed stuck process $pid_to_wait after 10s timeout" + else + wait "$pid_to_wait" + fi + pids=("${pids[@]:1}") + pid_start_times=("${pid_start_times[@]:1}") + ((job_count--)) + fi + # Start background job with higher priority + (update_tags "lxc" "$vmid") & + pids+=($!) + pid_start_times+=("$(date +%s)") + ((job_count++)) + done + for i in "${!pids[@]}"; do + local pid="${pids[$i]}" + local waited=0 + while kill -0 "$pid" 2>/dev/null && [[ $waited -lt 10 ]]; do + sleep 1 + ((waited++)) + done + if kill -0 "$pid" 2>/dev/null; then + kill -9 "$pid" 2>/dev/null + log_warning "LXC parallel: killed stuck process $pid after 10s timeout" + else + wait "$pid" + fi + done + debug_log "Completed parallel LXC processing" +} + +# Optimized LXC IP detection with caching and alternative methods +get_lxc_ips() { + local vmid=$1 + local status_cache_file="/tmp/iptag_lxc_status_${vmid}_cache" + local status_cache_ttl=${LXC_STATUS_CACHE_TTL:-30} + + debug_log "lxc $vmid: starting extreme optimized IP detection" + + # Check status cache first (avoid expensive pct status calls) + local lxc_status="" + if [[ -f "$status_cache_file" ]] && [[ $(($(date +%s) - $(stat -c %Y "$status_cache_file" 2>/dev/null || echo 0))) -lt $status_cache_ttl ]]; then + lxc_status=$(cat "$status_cache_file" 2>/dev/null) + debug_log "lxc $vmid: using cached status: $lxc_status" + else + lxc_status=$(pct status "${vmid}" 2>/dev/null | awk '{print $2}') + echo "$lxc_status" > "$status_cache_file" 2>/dev/null + debug_log "lxc $vmid: fetched fresh status: $lxc_status" + fi + + if [[ "$lxc_status" != "running" ]]; then + debug_log "lxc $vmid: not running (status: $lxc_status)" + return + fi + + local ips="" + local method_used="" + + # EXTREME Method 1: Direct Proxmox config inspection (super fast) + debug_log "lxc $vmid: trying direct Proxmox config inspection" + local pve_lxc_config="/etc/pve/lxc/${vmid}.conf" + if [[ -f "$pve_lxc_config" ]]; then + local static_ip=$(grep -E "^net[0-9]+:" "$pve_lxc_config" 2>/dev/null | grep -oE 'ip=([0-9]{1,3}\.){3}[0-9]{1,3}' | cut -d'=' -f2 | head -1) + debug_log "lxc $vmid: [CONFIG] static_ip='$static_ip' (from $pve_lxc_config)" + if [[ -n "$static_ip" && "$static_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + debug_log "lxc $vmid: found static IP $static_ip in Proxmox config" + ips="$static_ip" + method_used="proxmox_config" + fi + else + debug_log "lxc $vmid: [CONFIG] config file not found: $pve_lxc_config" + fi + + # EXTREME Method 2: Direct network namespace inspection (fastest dynamic) + if [[ -z "$ips" ]]; then + debug_log "lxc $vmid: trying optimized namespace inspection" + local ns_file="/var/lib/lxc/${vmid}/rootfs/proc/net/fib_trie" + if [[ -f "$ns_file" ]]; then + local ns_ip=$(timeout 1 grep -m1 -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' "$ns_file" 2>/dev/null | grep -v '127.0.0.1' | head -1) + debug_log "lxc $vmid: [NAMESPACE] ns_ip='$ns_ip'" + if [[ -n "$ns_ip" ]] && is_valid_ipv4 "$ns_ip"; then + debug_log "lxc $vmid: found IP $ns_ip via namespace inspection" + ips="$ns_ip" + method_used="namespace" + fi + else + debug_log "lxc $vmid: [NAMESPACE] ns_file not found: $ns_file" + fi + fi + + # EXTREME Method 3: Batch ARP table lookup (if namespace failed) + if [[ -z "$ips" ]]; then + debug_log "lxc $vmid: trying batch ARP lookup" + local bridge_name=""; local mac_addr="" + if [[ -f "$pve_lxc_config" ]]; then + bridge_name=$(grep -Eo 'bridge=[^,]+' "$pve_lxc_config" | head -1 | cut -d'=' -f2) + mac_addr=$(grep -Eo 'hwaddr=([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}' "$pve_lxc_config" | head -1 | cut -d'=' -f2) + debug_log "lxc $vmid: [ARP] bridge_name='$bridge_name' mac_addr='$mac_addr' (from $pve_lxc_config)" + fi + if [[ -z "$bridge_name" || -z "$mac_addr" ]]; then + local lxc_config="/var/lib/lxc/${vmid}/config" + if [[ -f "$lxc_config" ]]; then + [[ -z "$bridge_name" ]] && bridge_name=$(grep "lxc.net.0.link" "$lxc_config" 2>/dev/null | cut -d'=' -f2 | tr -d ' ') + [[ -z "$mac_addr" ]] && mac_addr=$(grep "lxc.net.0.hwaddr" "$lxc_config" 2>/dev/null | cut -d'=' -f2 | tr -d ' ') + debug_log "lxc $vmid: [ARP] bridge_name='$bridge_name' mac_addr='$mac_addr' (from $lxc_config)" + else + debug_log "lxc $vmid: [ARP] lxc config not found: $lxc_config" + fi + fi + if [[ -n "$bridge_name" && -n "$mac_addr" ]]; then + local bridge_ip=$(ip neighbor show dev "$bridge_name" 2>/dev/null | grep "$mac_addr" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1) + debug_log "lxc $vmid: [ARP] bridge_ip='$bridge_ip'" + if [[ -n "$bridge_ip" && "$bridge_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + debug_log "lxc $vmid: found IP $bridge_ip via ARP table" + ips="$bridge_ip" + method_used="arp_table" + fi + fi + fi + + # EXTREME Method 4: Fast process namespace (if ARP failed) + if [[ -z "$ips" ]] && [[ "${LXC_SKIP_SLOW_METHODS:-true}" != "true" ]]; then + debug_log "lxc $vmid: trying fast process namespace" + local pid_cache_file="/tmp/iptag_lxc_pid_${vmid}_cache" + local container_pid="" + if [[ -f "$pid_cache_file" ]] && [[ $(($(date +%s) - $(stat -c %Y "$pid_cache_file" 2>/dev/null || echo 0))) -lt 60 ]]; then + container_pid=$(cat "$pid_cache_file" 2>/dev/null) + else + container_pid=$(pct list 2>/dev/null | grep "^$vmid" | awk '{print $3}') + [[ -n "$container_pid" && "$container_pid" != "-" ]] && echo "$container_pid" > "$pid_cache_file" + fi + debug_log "lxc $vmid: [PROCESS_NS] container_pid='$container_pid'" + if [[ -n "$container_pid" && "$container_pid" != "-" ]]; then + local ns_ip=$(timeout 1 nsenter -t "$container_pid" -n ip -4 addr show 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127.0.0.1' | head -1) + debug_log "lxc $vmid: [PROCESS_NS] ns_ip='$ns_ip'" + if [[ -n "$ns_ip" ]] && is_valid_ipv4 "$ns_ip"; then + debug_log "lxc $vmid: found IP $ns_ip via process namespace" + ips="$ns_ip" + method_used="process_ns" + fi + fi + fi + + # Fallback: always do lxc-attach/pct exec with timeout if nothing found + if [[ -z "$ips" && "${LXC_ALLOW_FORCED_COMMANDS:-true}" == "true" ]]; then + debug_log "lxc $vmid: trying fallback lxc-attach (forced)" + local attach_ip="" + attach_ip=$(timeout 7s lxc-attach -n "$vmid" -- ip -4 addr show 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127.0.0.1' | head -1) + local attach_status=$? + debug_log "lxc $vmid: [LXC_ATTACH] attach_ip='$attach_ip' status=$attach_status" + if [[ $attach_status -eq 124 ]]; then + debug_log "lxc $vmid: lxc-attach timed out after 7s" + fi + if [[ -n "$attach_ip" ]] && is_valid_ipv4 "$attach_ip"; then + debug_log "lxc $vmid: found IP $attach_ip via lxc-attach (forced)" + ips="$attach_ip" + method_used="lxc_attach_forced" + fi + fi + if [[ -z "$ips" && "${LXC_ALLOW_FORCED_COMMANDS:-true}" == "true" ]]; then + debug_log "lxc $vmid: trying fallback pct exec (forced)" + local pct_ip="" + pct_ip=$(timeout 7s pct exec "$vmid" -- ip -4 addr show 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127.0.0.1' | head -1) + local pct_status=$? + debug_log "lxc $vmid: [PCT_EXEC] pct_ip='$pct_ip' status=$pct_status" + if [[ $pct_status -eq 124 ]]; then + debug_log "lxc $vmid: pct exec timed out after 7s" + fi + if [[ -n "$pct_ip" ]] && is_valid_ipv4 "$pct_ip"; then + debug_log "lxc $vmid: found IP $pct_ip via pct exec (forced)" + ips="$pct_ip" + method_used="pct_exec_forced" + fi + fi + + debug_log "lxc $vmid: [RESULT] ips='$ips' method='$method_used'" + echo "$ips" +} + +main +EOF +} + +# Main installation process +if check_service_exists; then + while true; do + read -p "IP-Tag service is already installed. Do you want to update it? (y/n): " yn + case $yn in + [Yy]*) + update_installation + exit 0 + ;; + [Nn]*) + msg_error "Installation cancelled." + exit 0 + ;; + *) + msg_error "Please answer yes or no." + ;; + esac + done +fi + +while true; do + read -p "This will install ${APP} on ${hostname}. Proceed? (y/n): " yn + case $yn in + [Yy]*) + break + ;; + [Nn]*) + msg_error "Installation cancelled." + exit + ;; + *) + msg_error "Please answer yes or no." + ;; + esac +done + +if ! pveversion | grep -Eq "pve-manager/8\.[0-4](\.[0-9]+)*"; then + msg_error "This version of Proxmox Virtual Environment is not supported" + msg_error "⚠️ Requires Proxmox Virtual Environment Version 8.0 or later." + msg_error "Exiting..." + sleep 2 + exit +fi + +FILE_PATH="/usr/local/bin/iptag" +if [[ -f "$FILE_PATH" ]]; then + msg_info "The file already exists: '$FILE_PATH'. Skipping installation." + exit 0 +fi + +msg_info "Installing Dependencies" +apt-get update &>/dev/null +apt-get install -y ipcalc net-tools &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Setting up IP-Tag Scripts" +mkdir -p /opt/iptag +msg_ok "Setup IP-Tag Scripts" + +# Migrate config if needed +migrate_config + +msg_info "Setup Default Config" +if [[ ! -f /opt/iptag/iptag.conf ]]; then + generate_config >/opt/iptag/iptag.conf + msg_ok "Setup default config" +else + msg_ok "Default config already exists" +fi + +msg_info "Setup Main Function" +if [[ ! -f /opt/iptag/iptag ]]; then + generate_main_script >/opt/iptag/iptag + chmod +x /opt/iptag/iptag + msg_ok "Setup Main Function" +else + msg_ok "Main Function already exists" +fi + +msg_info "Creating Service" +if [[ ! -f /lib/systemd/system/iptag.service ]]; then + generate_service >/lib/systemd/system/iptag.service + msg_ok "Created Service" +else + msg_ok "Service already exists." +fi + +msg_ok "Setup IP-Tag Scripts" + +msg_info "Starting Service" +systemctl daemon-reload &>/dev/null +systemctl enable -q --now iptag.service &>/dev/null +msg_ok "Started Service" + +msg_info "Restarting Service with optimizations" +systemctl restart iptag.service &>/dev/null +msg_ok "Service restarted with CPU optimizations" + +msg_info "Creating manual run command" +cat <<'EOF' >/usr/local/bin/iptag-run +#!/usr/bin/env bash +CONFIG_FILE="/opt/iptag/iptag.conf" +SCRIPT_FILE="/opt/iptag/iptag" +if [[ ! -f "$SCRIPT_FILE" ]]; then + echo "❌ Main script not found: $SCRIPT_FILE" + exit 1 +fi +export FORCE_SINGLE_RUN=true +exec "$SCRIPT_FILE" +EOF +chmod +x /usr/local/bin/iptag-run +msg_ok "Created iptag-run executable - You can execute this manually by entering “iptag-run” in the Proxmox host, so the script is executed by hand." + +SPINNER_PID="" +echo -e "\n${APP} installation completed successfully! ${CL}\n" + +# Proper script termination +exit 0 From 1f21b4dc8613b362938f2100915f52f2a0753e55 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 12:12:23 +0200 Subject: [PATCH 390/463] Update add-iptag.sh --- tools/pve/add-iptag.sh | 124 +++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 73 deletions(-) diff --git a/tools/pve/add-iptag.sh b/tools/pve/add-iptag.sh index 49bf1a90..6dbda4df 100644 --- a/tools/pve/add-iptag.sh +++ b/tools/pve/add-iptag.sh @@ -194,12 +194,14 @@ CIDR_LIST=( 10.0.0.0/8 100.64.0.0/10 ) +# Enable or Disable IPv6 tagging +ENABLE_IPV6_TAGS=false # Tag format options: # - "full": full IP address (e.g., 192.168.0.100) # - "last_octet": only the last octet (e.g., 100) # - "last_two_octets": last two octets (e.g., 0.100) -TAG_FORMAT="last_two_octets" +TAG_FORMAT="full" # Interval settings (in seconds) - optimized for lower CPU usage LOOP_INTERVAL=300 @@ -1088,14 +1090,23 @@ process_lxc_parallel() { } # Optimized LXC IP detection with caching and alternative methods +# ------------------------------------------- +# Combined optimized LXC IP detection +# Keeps advanced debug logs & methods +# Adds IPv6 detection controlled by ENABLE_IPV6_TAGS +# ------------------------------------------- get_lxc_ips() { local vmid=$1 + local ips="" + local method_used="" + + # status cache for container state local status_cache_file="/tmp/iptag_lxc_status_${vmid}_cache" local status_cache_ttl=${LXC_STATUS_CACHE_TTL:-30} - debug_log "lxc $vmid: starting extreme optimized IP detection" + debug_log "lxc $vmid: starting combined IP detection" - # Check status cache first (avoid expensive pct status calls) + # ----- STATUS CHECK ----- local lxc_status="" if [[ -f "$status_cache_file" ]] && [[ $(($(date +%s) - $(stat -c %Y "$status_cache_file" 2>/dev/null || echo 0))) -lt $status_cache_ttl ]]; then lxc_status=$(cat "$status_cache_file" 2>/dev/null) @@ -1111,74 +1122,48 @@ get_lxc_ips() { return fi - local ips="" - local method_used="" - - # EXTREME Method 1: Direct Proxmox config inspection (super fast) - debug_log "lxc $vmid: trying direct Proxmox config inspection" + # ----- TRY CONFIG FOR STATIC IP ----- local pve_lxc_config="/etc/pve/lxc/${vmid}.conf" if [[ -f "$pve_lxc_config" ]]; then local static_ip=$(grep -E "^net[0-9]+:" "$pve_lxc_config" 2>/dev/null | grep -oE 'ip=([0-9]{1,3}\.){3}[0-9]{1,3}' | cut -d'=' -f2 | head -1) - debug_log "lxc $vmid: [CONFIG] static_ip='$static_ip' (from $pve_lxc_config)" + debug_log "lxc $vmid: [CONFIG] static_ip='$static_ip'" if [[ -n "$static_ip" && "$static_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then - debug_log "lxc $vmid: found static IP $static_ip in Proxmox config" ips="$static_ip" method_used="proxmox_config" fi - else - debug_log "lxc $vmid: [CONFIG] config file not found: $pve_lxc_config" fi - # EXTREME Method 2: Direct network namespace inspection (fastest dynamic) + # ----- NAMESPACE FAST PARSE ----- if [[ -z "$ips" ]]; then - debug_log "lxc $vmid: trying optimized namespace inspection" local ns_file="/var/lib/lxc/${vmid}/rootfs/proc/net/fib_trie" + debug_log "lxc $vmid: trying namespace fib_trie" if [[ -f "$ns_file" ]]; then local ns_ip=$(timeout 1 grep -m1 -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' "$ns_file" 2>/dev/null | grep -v '127.0.0.1' | head -1) - debug_log "lxc $vmid: [NAMESPACE] ns_ip='$ns_ip'" if [[ -n "$ns_ip" ]] && is_valid_ipv4 "$ns_ip"; then - debug_log "lxc $vmid: found IP $ns_ip via namespace inspection" ips="$ns_ip" - method_used="namespace" + method_used="namespace_fib" + debug_log "lxc $vmid: found IP via namespace: $ips" fi - else - debug_log "lxc $vmid: [NAMESPACE] ns_file not found: $ns_file" fi fi - # EXTREME Method 3: Batch ARP table lookup (if namespace failed) + # ----- ARP TABLE ----- if [[ -z "$ips" ]]; then - debug_log "lxc $vmid: trying batch ARP lookup" - local bridge_name=""; local mac_addr="" - if [[ -f "$pve_lxc_config" ]]; then - bridge_name=$(grep -Eo 'bridge=[^,]+' "$pve_lxc_config" | head -1 | cut -d'=' -f2) - mac_addr=$(grep -Eo 'hwaddr=([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}' "$pve_lxc_config" | head -1 | cut -d'=' -f2) - debug_log "lxc $vmid: [ARP] bridge_name='$bridge_name' mac_addr='$mac_addr' (from $pve_lxc_config)" - fi - if [[ -z "$bridge_name" || -z "$mac_addr" ]]; then - local lxc_config="/var/lib/lxc/${vmid}/config" - if [[ -f "$lxc_config" ]]; then - [[ -z "$bridge_name" ]] && bridge_name=$(grep "lxc.net.0.link" "$lxc_config" 2>/dev/null | cut -d'=' -f2 | tr -d ' ') - [[ -z "$mac_addr" ]] && mac_addr=$(grep "lxc.net.0.hwaddr" "$lxc_config" 2>/dev/null | cut -d'=' -f2 | tr -d ' ') - debug_log "lxc $vmid: [ARP] bridge_name='$bridge_name' mac_addr='$mac_addr' (from $lxc_config)" - else - debug_log "lxc $vmid: [ARP] lxc config not found: $lxc_config" - fi - fi - if [[ -n "$bridge_name" && -n "$mac_addr" ]]; then - local bridge_ip=$(ip neighbor show dev "$bridge_name" 2>/dev/null | grep "$mac_addr" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1) - debug_log "lxc $vmid: [ARP] bridge_ip='$bridge_ip'" + debug_log "lxc $vmid: trying ARP lookup" + local mac_addr=$(grep -Eo 'hwaddr=([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}' "$pve_lxc_config" | head -1 | cut -d'=' -f2 | tr 'A-F' 'a-f') + if [[ -n "$mac_addr" ]]; then + local bridge_ip=$(ip neighbor show | grep "$mac_addr" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1) if [[ -n "$bridge_ip" && "$bridge_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then - debug_log "lxc $vmid: found IP $bridge_ip via ARP table" ips="$bridge_ip" method_used="arp_table" + debug_log "lxc $vmid: found IP via ARP: $ips" fi fi fi - # EXTREME Method 4: Fast process namespace (if ARP failed) - if [[ -z "$ips" ]] && [[ "${LXC_SKIP_SLOW_METHODS:-true}" != "true" ]]; then - debug_log "lxc $vmid: trying fast process namespace" + # ----- PROCESS NAMESPACE (fast) ----- + if [[ -z "$ips" && "${LXC_SKIP_SLOW_METHODS:-true}" != "true" ]]; then + debug_log "lxc $vmid: trying process namespace" local pid_cache_file="/tmp/iptag_lxc_pid_${vmid}_cache" local container_pid="" if [[ -f "$pid_cache_file" ]] && [[ $(($(date +%s) - $(stat -c %Y "$pid_cache_file" 2>/dev/null || echo 0))) -lt 60 ]]; then @@ -1187,54 +1172,47 @@ get_lxc_ips() { container_pid=$(pct list 2>/dev/null | grep "^$vmid" | awk '{print $3}') [[ -n "$container_pid" && "$container_pid" != "-" ]] && echo "$container_pid" > "$pid_cache_file" fi - debug_log "lxc $vmid: [PROCESS_NS] container_pid='$container_pid'" if [[ -n "$container_pid" && "$container_pid" != "-" ]]; then local ns_ip=$(timeout 1 nsenter -t "$container_pid" -n ip -4 addr show 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127.0.0.1' | head -1) - debug_log "lxc $vmid: [PROCESS_NS] ns_ip='$ns_ip'" if [[ -n "$ns_ip" ]] && is_valid_ipv4 "$ns_ip"; then - debug_log "lxc $vmid: found IP $ns_ip via process namespace" ips="$ns_ip" method_used="process_ns" + debug_log "lxc $vmid: found IP via process namespace: $ips" fi fi fi - # Fallback: always do lxc-attach/pct exec with timeout if nothing found - if [[ -z "$ips" && "${LXC_ALLOW_FORCED_COMMANDS:-true}" == "true" ]]; then - debug_log "lxc $vmid: trying fallback lxc-attach (forced)" - local attach_ip="" - attach_ip=$(timeout 7s lxc-attach -n "$vmid" -- ip -4 addr show 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127.0.0.1' | head -1) - local attach_status=$? - debug_log "lxc $vmid: [LXC_ATTACH] attach_ip='$attach_ip' status=$attach_status" - if [[ $attach_status -eq 124 ]]; then - debug_log "lxc $vmid: lxc-attach timed out after 7s" - fi - if [[ -n "$attach_ip" ]] && is_valid_ipv4 "$attach_ip"; then - debug_log "lxc $vmid: found IP $attach_ip via lxc-attach (forced)" - ips="$attach_ip" - method_used="lxc_attach_forced" - fi - fi - if [[ -z "$ips" && "${LXC_ALLOW_FORCED_COMMANDS:-true}" == "true" ]]; then - debug_log "lxc $vmid: trying fallback pct exec (forced)" - local pct_ip="" - pct_ip=$(timeout 7s pct exec "$vmid" -- ip -4 addr show 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127.0.0.1' | head -1) - local pct_status=$? - debug_log "lxc $vmid: [PCT_EXEC] pct_ip='$pct_ip' status=$pct_status" - if [[ $pct_status -eq 124 ]]; then - debug_log "lxc $vmid: pct exec timed out after 7s" - fi + # ----- FORCED METHODS (attach/exec) ----- + if [[ -z "$ips" && "${LXC_ALLOW_FORCED_COMMANDS:-false}" == "true" ]]; then + debug_log "lxc $vmid: trying forced pct exec" + local pct_ip=$(timeout 7s pct exec "$vmid" -- ip -4 addr show 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127.0.0.1' | head -1) if [[ -n "$pct_ip" ]] && is_valid_ipv4 "$pct_ip"; then - debug_log "lxc $vmid: found IP $pct_ip via pct exec (forced)" ips="$pct_ip" method_used="pct_exec_forced" + debug_log "lxc $vmid: found IP via pct exec: $ips" fi fi + # ----- OPTIONAL IPv6 detection ----- + if [[ -z "$ips" && "${ENABLE_IPV6_TAGS,,}" == "true" ]]; then + debug_log "lxc $vmid: trying IPv6 neighbor lookup" + local mac_addr=$(grep -Eo 'hwaddr=([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}' "$pve_lxc_config" | head -1 | cut -d'=' -f2 | tr 'A-F' 'a-f') + if [[ -n "$mac_addr" ]]; then + local ipv6=$(ip -6 neighbor show | grep -i "$mac_addr" | grep -oE '([0-9a-fA-F:]+:+)+' | head -1) + if [[ -n "$ipv6" ]]; then + ips="$ipv6" + method_used="ipv6_neighbor" + debug_log "lxc $vmid: found IPv6: $ips" + fi + fi + fi + + # ----- FINAL RESULT ----- debug_log "lxc $vmid: [RESULT] ips='$ips' method='$method_used'" echo "$ips" } + main EOF } From 0aaf8cfd1c5656509ca6dddfe87d2e2db014556a Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 12:52:50 +0200 Subject: [PATCH 391/463] Update add-iptag.sh --- tools/pve/add-iptag.sh | 66 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/tools/pve/add-iptag.sh b/tools/pve/add-iptag.sh index 6dbda4df..50dac8b9 100644 --- a/tools/pve/add-iptag.sh +++ b/tools/pve/add-iptag.sh @@ -203,6 +203,12 @@ ENABLE_IPV6_TAGS=false # - "last_two_octets": last two octets (e.g., 0.100) TAG_FORMAT="full" +# IPv6 Tag format options: +# - "full": full IPv6 address +# - "short": compressed form (default) +# - "last_block": only last block +IPV6_TAG_FORMAT="short" + # Interval settings (in seconds) - optimized for lower CPU usage LOOP_INTERVAL=300 VM_STATUS_CHECK_INTERVAL=600 @@ -360,6 +366,33 @@ format_ip_tag() { esac } +format_ipv6_tag() { + local ip="$1" + [[ -z "$ip" ]] && return + local format="${IPV6_TAG_FORMAT:-short}" + + case "$format" in + "last_block") + # take last hex block + echo "${ip##*:}" + ;; + "full") + # return full as-is + echo "$ip" + ;; + "short"|"compressed") + # compress repeated zeros (::) automatically + # Linux ip command already returns compressed by default + echo "$ip" + ;; + *) + # fallback + echo "$ip" + ;; + esac +} + + # Check if IP is in any CIDRs ip_in_cidrs() { local ip="$1" cidrs="$2" @@ -626,22 +659,41 @@ update_tags() { for ip in $current_ips_full; do [[ -z "$ip" ]] && continue debug_log "$type $vmid processing IP: '$ip'" + if is_valid_ipv4 "$ip"; then - debug_log "$type $vmid IP '$ip' is valid" + debug_log "$type $vmid IP '$ip' is valid IPv4" + # Only check IPv4 against CIDR list if ip_in_cidrs "$ip" "${CIDR_LIST[*]}"; then - debug_log "$type $vmid IP '$ip' passed CIDR check" - local formatted_ip=$(format_ip_tag "$ip") - debug_log "$type $vmid formatted '$ip' -> '$formatted_ip'" - [[ -n "$formatted_ip" ]] && formatted_ips+=("$formatted_ip") + debug_log "$type $vmid IPv4 '$ip' passed CIDR check" + local formatted_ip4 + formatted_ip4=$(format_ip_tag "$ip") + debug_log "$type $vmid formatted IPv4 '$ip' -> '$formatted_ip4'" + [[ -n "$formatted_ip4" ]] && formatted_ips+=("$formatted_ip4") else - debug_log "$type $vmid IP '$ip' failed CIDR check" + debug_log "$type $vmid IPv4 '$ip' failed CIDR check, skipping" fi + + elif [[ "${ENABLE_IPV6_TAGS,,}" == "true" ]]; then + # IPv6 handling only if enabled + debug_log "$type $vmid IP '$ip' not IPv4, treating as IPv6" + # basic IPv6 validation + if [[ "$ip" =~ ^[0-9a-fA-F:]+$ ]]; then + debug_log "$type $vmid IPv6 '$ip' accepted" + local formatted_ip6 + formatted_ip6=$(format_ipv6_tag "$ip") + debug_log "$type $vmid formatted IPv6 '$ip' -> '$formatted_ip6'" + [[ -n "$formatted_ip6" ]] && formatted_ips+=("$formatted_ip6") + else + debug_log "$type $vmid value '$ip' not recognized as valid IPv6, skipping" + fi + else - debug_log "$type $vmid IP '$ip' is invalid" + debug_log "$type $vmid IP '$ip' is invalid or IPv6 not enabled" fi done debug_log "$type $vmid final formatted_ips: ${formatted_ips[*]}" + # If LXC and no IPs detected, do not touch tags at all if [[ "$type" == "lxc" && ${#formatted_ips[@]} -eq 0 ]]; then log_unchanged "LXC ${GRAY}${vmid}${NC}: No IP detected, tags unchanged" From ad62a8ad0def341cc8931c5ec68aad53d81a0e9d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 12:57:12 +0200 Subject: [PATCH 392/463] Update add-iptag.sh --- tools/pve/add-iptag.sh | 43 ++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/tools/pve/add-iptag.sh b/tools/pve/add-iptag.sh index 50dac8b9..742a07a0 100644 --- a/tools/pve/add-iptag.sh +++ b/tools/pve/add-iptag.sh @@ -195,7 +195,7 @@ CIDR_LIST=( 100.64.0.0/10 ) # Enable or Disable IPv6 tagging -ENABLE_IPV6_TAGS=false +ENABLE_IPV6_TAGS=true # Tag format options: # - "full": full IP address (e.g., 192.168.0.100) @@ -228,8 +228,8 @@ MAX_PARALLEL_LXC_CHECKS=2 LXC_BATCH_SIZE=3 LXC_STATUS_CACHE_TTL=300 LXC_AGGRESSIVE_CACHING=true -LXC_SKIP_SLOW_METHODS=true -LXC_ALLOW_FORCED_COMMANDS=false +LXC_SKIP_SLOW_METHODS=false +LXC_ALLOW_FORCED_COMMANDS=true # Debug settings (set to true to enable debugging) DEBUG=false @@ -1246,15 +1246,34 @@ get_lxc_ips() { fi # ----- OPTIONAL IPv6 detection ----- - if [[ -z "$ips" && "${ENABLE_IPV6_TAGS,,}" == "true" ]]; then - debug_log "lxc $vmid: trying IPv6 neighbor lookup" - local mac_addr=$(grep -Eo 'hwaddr=([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}' "$pve_lxc_config" | head -1 | cut -d'=' -f2 | tr 'A-F' 'a-f') - if [[ -n "$mac_addr" ]]; then - local ipv6=$(ip -6 neighbor show | grep -i "$mac_addr" | grep -oE '([0-9a-fA-F:]+:+)+' | head -1) - if [[ -n "$ipv6" ]]; then - ips="$ipv6" - method_used="ipv6_neighbor" - debug_log "lxc $vmid: found IPv6: $ips" + if [[ "${ENABLE_IPV6_TAGS,,}" == "true" ]]; then + debug_log "lxc $vmid: IPv6 detection enabled" + + # 1. Try to get IPv6 from inside the container + local pct_ipv6=$(timeout 3 pct exec "$vmid" -- ip -6 addr show scope global 2>/dev/null \ + | grep -oE '([0-9a-fA-F]{0,4}:){2,7}[0-9a-fA-F]{0,4}' \ + | grep -v '^fe80' | head -1) + if [[ -n "$pct_ipv6" ]]; then + debug_log "lxc $vmid: found IPv6 via pct exec: $pct_ipv6" + [[ -n "$ips" ]] && ips="$ips $pct_ipv6" || ips="$pct_ipv6" + method_used="${method_used:+$method_used,}ipv6_exec" + else + debug_log "lxc $vmid: no IPv6 from pct exec, fallback to neighbor table" + + # 2. Fallback: neighbor table + local mac_addr=$(grep -Eo 'hwaddr=([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}' "$pve_lxc_config" \ + | head -1 | cut -d'=' -f2 | tr 'A-F' 'a-f') + if [[ -n "$mac_addr" ]]; then + local ipv6_nb=$(ip -6 neighbor show | grep -i "$mac_addr" \ + | grep -oE '([0-9a-fA-F]{0,4}:){2,7}[0-9a-fA-F]{0,4}' \ + | grep -v '^fe80' | head -1) + if [[ -n "$ipv6_nb" ]]; then + debug_log "lxc $vmid: found IPv6 via neighbor: $ipv6_nb" + [[ -n "$ips" ]] && ips="$ips $ipv6_nb" || ips="$ipv6_nb" + method_used="${method_used:+$method_used,}ipv6_neighbor" + else + debug_log "lxc $vmid: no IPv6 found in neighbor table" + fi fi fi fi From b5759dda481111b24d2e4b4576c7e41388af2112 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 13:14:10 +0200 Subject: [PATCH 393/463] rybbit --- install/docspell-install.sh | 2 +- install/rybbit-install.sh | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/install/docspell-install.sh b/install/docspell-install.sh index d76983d2..8b963d18 100644 --- a/install/docspell-install.sh +++ b/install/docspell-install.sh @@ -59,7 +59,7 @@ msg_ok "Set up PostgreSQL Database" fetch_and_deploy_gh_release "docspell-joex" "eikek/docspell" "binary" "latest" "/opt/docspell-joex" "docspell-joex_*all.deb" fetch_and_deploy_gh_release "docspell-restserver" "eikek/docspell" "binary" "latest" "/opt/docspell-restserver" "docspell-restserver_*all.deb" fetch_and_deploy_gh_release "docspell-dsc" "docspell/dsc" "singlefile" "latest" "/usr/bin" "dsc" - +fetch_and_deploy_gh_release "apache-solr" "apache/solr" "tarball" "latest" "/opt/docspell" msg_info "Setup Docspell" diff --git a/install/rybbit-install.sh b/install/rybbit-install.sh index 56f82bcd..c7d913d9 100644 --- a/install/rybbit-install.sh +++ b/install/rybbit-install.sh @@ -48,6 +48,32 @@ msg_ok "Set up PostgreSQL Database" fetch_and_deploy_gh_release "rybbit" "rybbit-io/rybbit" "tarball" "latest" "/opt/rybbit" +cd /opt/rybbit/shared +npm install +npm run build + +cd /opt/rybbit/server +RUN npm ci +npm run build + +cd /opt/rybbit/client +npm ci --legacy-peer-deps +npm run build + +mv /opt/rybbit/.env.example /opt/rybbit/.env +sed -i "s|^POSTGRES_DB=.*|POSTGRES_DB=$DB_NAME|g" /opt/rybbit/.env +sed -i "s|^POSTGRES_USER=.*|POSTGRES_USER=$DB_USER|g" /opt/rybbit/.env +sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$DB_PASS|g" /opt/rybbit/.env +sed -i "s|^DOMAIN_NAME=.*|DOMAIN_NAME=localhost|g" /opt/rybbit/.env +sed -i "s|^BASE_URL=.*|BASE_URL=\"http://localhost\"|g" /opt/rybbit/.env +msg_ok "Rybbit Installed" + +msg_info "Setting up Caddy" +mkdir -p /etc/caddy +cp /opt/rybbit/Caddyfile /etc/caddy/Caddyfile +systemctl enable -q --now caddy +msg_ok "Caddy Setup" + motd_ssh customize From 62e2b07dabf8ca362351b0ebaf44931e289486c3 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 13:18:43 +0200 Subject: [PATCH 394/463] Update viseron-install.sh --- install/viseron-install.sh | 41 +++++++++++++------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/install/viseron-install.sh b/install/viseron-install.sh index 3f04fdf6..cc30bcd9 100644 --- a/install/viseron-install.sh +++ b/install/viseron-install.sh @@ -13,42 +13,29 @@ setting_up_container network_check update_os +PYTHON_VERSION="3.12" setup_uv + + msg_info "Installing Dependencies" $STD apt-get install -y \ -python3 python3-pip python3-venv \ -git curl wget \ -libgl1-mesa-glx libglib2.0-0 \ -libsm6 libxext6 libxrender-dev \ -libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 \ -libgstreamer-plugins-bad1.0-0 gstreamer1.0-plugins-base \ -gstreamer1.0-plugins-good gstreamer1.0-plugins-bad \ -gstreamer1.0-plugins-ugly gstreamer1.0-libav \ -gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa \ -gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 \ -gstreamer1.0-pulseaudio \ -libavcodec-dev libavformat-dev libswscale-dev \ -libv4l-dev libxvidcore-dev libx264-dev \ -libjpeg-dev libpng-dev libtiff-dev \ -libatlas-base-dev gfortran \ -libhdf5-dev libhdf5-serial-dev \ -libhdf5-103 libqtgui4 libqtwebkit4 libqt4-test python3-pyqt5 \ -libgtk-3-dev libcanberra-gtk3-module \ -libgirepository1.0-dev libcairo2-dev pkg-config \ -libcblas-dev libopenblas-dev liblapack-dev \ -libsm6 libxext6 libxrender-dev libxss1 \ -libgconf-2-4 libasound2 + python3 python3-pip python3-venv \ + python3-opencv \ + libgl1-mesa-glx libglib2.0-0 \ + libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 \ + gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-libav msg_ok "Installed Dependencies" -msg_info "Setting up Python Environment" +msg_info "Setting up Python Environment with uv" cd /opt -python3 -m venv viseron +uv venv viseron source viseron/bin/activate -pip install --upgrade pip setuptools wheel -msg_ok "Python Environment Setup" +uv pip install --upgrade pip setuptools wheel +msg_ok "Python Environment Setup (uv)" msg_info "Installing Viseron" RELEASE=$(curl -s https://api.github.com/repos/roflcoopter/viseron/releases/latest | jq -r '.tag_name') -pip install viseron==${RELEASE#v} +uv pip install viseron==${RELEASE#v} +ln -s /opt/viseron/bin/viseron /usr/local/bin/viseron msg_ok "Installed Viseron $RELEASE" msg_info "Creating Configuration Directory" From ef67f58e2e925659438291ed0f24f208cbde396b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 13:19:03 +0200 Subject: [PATCH 395/463] Update rybbit-install.sh --- install/rybbit-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/rybbit-install.sh b/install/rybbit-install.sh index c7d913d9..4865a0d8 100644 --- a/install/rybbit-install.sh +++ b/install/rybbit-install.sh @@ -53,7 +53,7 @@ npm install npm run build cd /opt/rybbit/server -RUN npm ci +npm ci npm run build cd /opt/rybbit/client From ddf9148dc0164b5333a2eb61f6d64d4399ae7e95 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 13:27:47 +0200 Subject: [PATCH 396/463] fixes --- install/viseron-install.sh | 1 - tools/pve/post-pve-install.sh | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/install/viseron-install.sh b/install/viseron-install.sh index cc30bcd9..6964180d 100644 --- a/install/viseron-install.sh +++ b/install/viseron-install.sh @@ -15,7 +15,6 @@ update_os PYTHON_VERSION="3.12" setup_uv - msg_info "Installing Dependencies" $STD apt-get install -y \ python3 python3-pip python3-venv \ diff --git a/tools/pve/post-pve-install.sh b/tools/pve/post-pve-install.sh index 5afc3bd0..79a5f809 100644 --- a/tools/pve/post-pve-install.sh +++ b/tools/pve/post-pve-install.sh @@ -141,7 +141,7 @@ EOF yes) whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 msg_info "Disabling subscription nag" - echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/.*data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit 2>/dev/null && [ -f /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js ] && echo 'Removing subscription nag from UI...' && sed -i '/data\.status/{s/\!/=/;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled subscription nag (Delete browser cache)" ;; From f2c5bf774cb8448b2b38c2e39c53a1ad82b8e626 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 13:28:55 +0200 Subject: [PATCH 397/463] Update post-pve-install.sh --- tools/pve/post-pve-install.sh | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/tools/pve/post-pve-install.sh b/tools/pve/post-pve-install.sh index 79a5f809..f241aca1 100644 --- a/tools/pve/post-pve-install.sh +++ b/tools/pve/post-pve-install.sh @@ -246,12 +246,38 @@ while true; do esac done -if ! pveversion | grep -Eq "pve-manager/8\.[0-4](\.[0-9]+)*"; then +# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. +pve_check() { + local PVE_VER + PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')" + + # 8 Version Check + if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then + local MINOR="${BASH_REMATCH[1]}" + if (( MINOR < 1 || MINOR > 4 )); then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires Proxmox Virtual Environment Version 8.1 – 8.4" + echo -e "Exiting..." + sleep 2 + exit 1 + fi + return 0 + fi + + # 9 Beta Version Check + if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then + msg_custom "Detected Proxmox Virtual Environment $PVE_VER – Beta state, use with caution!" + return 0 + fi + + # All others (unsupported versions) msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires Proxmox Virtual Environment Version 8.0 or later." + echo -e "Requires Proxmox Virtual Environment Version 8.1 – 8.4 or 9.x (Beta)" echo -e "Exiting..." sleep 2 - exit -fi + exit 1 +} + +pve_check start_routines From 2a3b9454e7feb48642f6ce26e0867a334fdb4c74 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 13:30:23 +0200 Subject: [PATCH 398/463] Update viseron-install.sh --- install/viseron-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/viseron-install.sh b/install/viseron-install.sh index 6964180d..080da234 100644 --- a/install/viseron-install.sh +++ b/install/viseron-install.sh @@ -18,7 +18,7 @@ PYTHON_VERSION="3.12" setup_uv msg_info "Installing Dependencies" $STD apt-get install -y \ python3 python3-pip python3-venv \ - python3-opencv \ + python3-opencv \ jq \ libgl1-mesa-glx libglib2.0-0 \ libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 \ gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-libav From 48395202ccf0465b4ea124201ae4c75755e3fa3d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 13:31:06 +0200 Subject: [PATCH 399/463] Update post-pve-install.sh --- tools/pve/post-pve-install.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/pve/post-pve-install.sh b/tools/pve/post-pve-install.sh index f241aca1..b6c704f0 100644 --- a/tools/pve/post-pve-install.sh +++ b/tools/pve/post-pve-install.sh @@ -44,6 +44,12 @@ msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } +msg_custom() { + local msg="$1" + echo -e "${BFR} ${YW}⚠ ${msg}${CL}" +} + + start_routines() { header_info From aebdae5dee9c01099a338d4dd580aa5b81e3936b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 13:39:49 +0200 Subject: [PATCH 400/463] Update viseron-install.sh --- install/viseron-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/viseron-install.sh b/install/viseron-install.sh index 080da234..c96fab40 100644 --- a/install/viseron-install.sh +++ b/install/viseron-install.sh @@ -18,7 +18,7 @@ PYTHON_VERSION="3.12" setup_uv msg_info "Installing Dependencies" $STD apt-get install -y \ python3 python3-pip python3-venv \ - python3-opencv \ jq \ + python3-opencv jq \ libgl1-mesa-glx libglib2.0-0 \ libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 \ gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-libav From 977e5a05eb94d8af70aeeda46c290ca9ebeae7e7 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 13:48:08 +0200 Subject: [PATCH 401/463] Update viseron-install.sh --- install/viseron-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/viseron-install.sh b/install/viseron-install.sh index c96fab40..13aea1b3 100644 --- a/install/viseron-install.sh +++ b/install/viseron-install.sh @@ -33,7 +33,7 @@ msg_ok "Python Environment Setup (uv)" msg_info "Installing Viseron" RELEASE=$(curl -s https://api.github.com/repos/roflcoopter/viseron/releases/latest | jq -r '.tag_name') -uv pip install viseron==${RELEASE#v} +uv pip install https://github.com/roflcoopter/viseron/archive/refs/tags/${RELEASE}.tar.gz ln -s /opt/viseron/bin/viseron /usr/local/bin/viseron msg_ok "Installed Viseron $RELEASE" From 23c6236b0248971ae9f862f1d9ef1fbf48c68d21 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 13:48:28 +0200 Subject: [PATCH 402/463] Update viseron.sh --- ct/viseron.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/viseron.sh b/ct/viseron.sh index 8c12645a..32cb237e 100644 --- a/ct/viseron.sh +++ b/ct/viseron.sh @@ -8,7 +8,7 @@ var_ram="${var_ram:-2048}" var_disk="${var_disk:-10}" var_os="${var_os:-debian}" var_version="${var_version:-12}" -var_unprivileged="${var_unprivileged:-0}" +var_unprivileged="${var_unprivileged:-1}" header_info "$APP" From a07064067bad1154c9a28db02c3934ce34d1c244 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 14:09:26 +0200 Subject: [PATCH 403/463] error handling --- misc/build.func | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/misc/build.func b/misc/build.func index 35c623ed..07d33f95 100644 --- a/misc/build.func +++ b/misc/build.func @@ -35,14 +35,18 @@ catch_errors() { # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { - source /dev/stdin <<<$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) - printf "\e[?25h" + local exit_code="$?" local line_number="$1" local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + printf "\e[?25h" + + + source /dev/stdin <<<$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) + local error_message="[ERROR] in line $line_number: exit code $exit_code: while executing command $command" post_update_to_api "failed" "${command}" echo -e "\n$error_message\n" + exit "$exit_code" if [[ -n "$CT_ID" ]]; then read -p "Remove this Container? " prompt @@ -53,6 +57,7 @@ error_handler() { fi fi } + # Check if the shell is using bash shell_check() { if [[ "$(basename "$SHELL")" != "bash" ]]; then @@ -1228,10 +1233,8 @@ build_container() { $PW " bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)" - RET=$? - if [[ $RET -ne 0 ]]; then - msg_error "rny: in line $LINENO: exit code $RET: while executing create_lxc.sh" - exit $RET + if [ $? -ne 0 ]; then + exit 200 fi LXC_CONFIG="/etc/pve/lxc/${CTID}.conf" @@ -1394,7 +1397,10 @@ EOF' fi msg_ok "Customized LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/"$var_install".sh)" $? + lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/"$var_install".sh)" + if [ $? -ne 0 ]; then + exit 100 + fi } # This function sets the description of the container. From d1976b23d84eca4b92b8bbeb01f0e316d5a51178 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 14:40:59 +0200 Subject: [PATCH 404/463] Update salt-install.sh --- install/salt-install.sh | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/install/salt-install.sh b/install/salt-install.sh index 7c74b7c1..4fe29a82 100644 --- a/install/salt-install.sh +++ b/install/salt-install.sh @@ -17,25 +17,23 @@ msg_info "Installing Dependencies" $STD apt-get install -y jq msg_ok "Installed Dependencies" -fetch_and_deploy_gh_release "salt" "saltstack/salt" "binary" "latest" "/opt/salt" "salt-master*_amd64.deb" +msg_info "Setup Salt Repo" +mkdir -p /etc/apt/keyrings +curl -fsSL https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public -o /etc/apt/keyrings/salt-archive-keyring.pgp +curl -fsSL https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.sources -o /etc/apt/sources.list.d/salt.sources +$STD apt-get update +msg_ok "Setup Salt Repo" -# msg_info "Setup Salt repo" -# mkdir -p /etc/apt/keyrings -# curl -fsSL https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public -o /etc/apt/keyrings/salt-archive-keyring.pgp -# curl -fsSL https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.sources -o /etc/apt/sources.list.d/salt.sources -# $STD apt-get update -# msg_ok "Setup Salt repo" - -# msg_info "Installing Salt Master" -# RELEASE=$(curl -fsSL https://api.github.com/repos/saltstack/salt/releases/latest | jq -r .tag_name | sed 's/^v//') -# cat </etc/apt/preferences.d/salt-pin-1001 -# Package: salt-* -# Pin: version ${RELEASE} -# Pin-Priority: 1001 -# EOF -# $STD apt-get install -y salt-master -# echo "${RELEASE}" >/~.salt -# msg_ok "Installed Salt Master" +msg_info "Installing Salt" +RELEASE=$(curl -fsSL https://api.github.com/repos/saltstack/salt/releases/latest | jq -r .tag_name | sed 's/^v//') +cat </etc/apt/preferences.d/salt-pin-1001 +Package: salt-* +Pin: version ${RELEASE} +Pin-Priority: 1001 +EOF +$STD apt-get install -y salt-master +echo "${RELEASE}" >/~.salt +msg_ok "Installed Salt" motd_ssh customize From 5d3ad7a459767192ff399612c47b50ab325c73b2 Mon Sep 17 00:00:00 2001 From: tremor021 Date: Mon, 21 Jul 2025 14:43:13 +0200 Subject: [PATCH 405/463] Add TeamSpeak Server script --- ct/teamspeak-server.sh | 0 install/teamspeak-server-install.sh | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 ct/teamspeak-server.sh create mode 100644 install/teamspeak-server-install.sh diff --git a/ct/teamspeak-server.sh b/ct/teamspeak-server.sh new file mode 100644 index 00000000..e69de29b diff --git a/install/teamspeak-server-install.sh b/install/teamspeak-server-install.sh new file mode 100644 index 00000000..e69de29b From ca03967f6af573a43917f3fc66172c076f22bfa1 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 14:53:07 +0200 Subject: [PATCH 406/463] Update salt.sh --- ct/salt.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/salt.sh b/ct/salt.sh index 5efed33c..c8a6cec7 100644 --- a/ct/salt.sh +++ b/ct/salt.sh @@ -30,12 +30,12 @@ function update_script() { fi RELEASE=$(curl -fsSL https://api.github.com/repos/saltstack/salt/releases/latest | jq -r .tag_name | sed 's/^v//') - if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + if [[ ! -f /~.salt ]] || [[ "${RELEASE}" != "$(cat /~.salt)" ]]; then msg_info "Updating $APP to ${RELEASE}" sed -i "s/^\(Pin: version \).*/\1${RELEASE}/" /etc/apt/preferences.d/salt-pin-1001 $STD apt-get update $STD apt-get upgrade -y - echo "${RELEASE}" >/opt/${APP}_version.txt + echo "${RELEASE}" >/~.salt msg_ok "Updated ${APP} to ${RELEASE}" else msg_ok "${APP} is already up to date (${RELEASE})" From b5be5439b470e3da16f22009df912ff1ffc48af9 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 14:56:36 +0200 Subject: [PATCH 407/463] Update salt.json --- frontend/public/json/salt.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/public/json/salt.json b/frontend/public/json/salt.json index 4c162aba..41750a2f 100644 --- a/frontend/public/json/salt.json +++ b/frontend/public/json/salt.json @@ -2,7 +2,7 @@ "name": "Salt", "slug": "salt", "categories": [ - 1 + 19 ], "date_created": "2025-07-02", "type": "ct", @@ -13,7 +13,7 @@ "documentation": "https://docs.saltproject.io/salt/install-guide/en/latest/", "website": "https://saltproject.io/", "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/saltmaster.svg", - "description": "Saltmaster is an open-source self-hosted application.", + "description": "SaltStack Salt is a software for automating the management and configuration of IT infrastructure and applications. It is an event-driven automation tool and framework used to deploy, configure, and manage complex IT systems. Its primary functions include configuration management, where it ensures consistent configurations and manages operating system deployment and software installation. It also automates and orchestrates routine IT processes and can create self-aware, self-healing systems.", "install_methods": [ { "type": "default", From c05054fc1f634b065e1bc48f29d7409eabb2b545 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 15:03:17 +0200 Subject: [PATCH 408/463] Update build.func --- misc/build.func | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/misc/build.func b/misc/build.func index 07d33f95..a1f68f1a 100644 --- a/misc/build.func +++ b/misc/build.func @@ -19,10 +19,12 @@ source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxV if command -v curl >/dev/null 2>&1; then source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) + source /dev/stdin <<<$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) load_functions #echo "(build.func) Loaded core.func via curl" elif command -v wget >/dev/null 2>&1; then source <(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) + source /dev/stdin <<<$(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) load_functions #echo "(build.func) Loaded core.func via wget" fi @@ -30,21 +32,18 @@ fi # This function enables error handling in the script by setting options and defining a trap for the ERR signal. catch_errors() { set -Eeo pipefail + shopt -s errtrace trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { - local exit_code="$?" local line_number="$1" local command="$2" printf "\e[?25h" - - - source /dev/stdin <<<$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) local error_message="[ERROR] in line $line_number: exit code $exit_code: while executing command $command" - post_update_to_api "failed" "${command}" + post_update_to_api "failed" "$command" echo -e "\n$error_message\n" exit "$exit_code" From 4c730e542d085e469f51b5cc848ec51b7b0d2814 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 15:04:38 +0200 Subject: [PATCH 409/463] Update build.func --- misc/build.func | 2 -- 1 file changed, 2 deletions(-) diff --git a/misc/build.func b/misc/build.func index a1f68f1a..a1494f92 100644 --- a/misc/build.func +++ b/misc/build.func @@ -19,12 +19,10 @@ source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxV if command -v curl >/dev/null 2>&1; then source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) - source /dev/stdin <<<$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) load_functions #echo "(build.func) Loaded core.func via curl" elif command -v wget >/dev/null 2>&1; then source <(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) - source /dev/stdin <<<$(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) load_functions #echo "(build.func) Loaded core.func via wget" fi From 219e800870616e323967e6bafb68c809ef8f3fa3 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 15:05:37 +0200 Subject: [PATCH 410/463] Update build.func --- misc/build.func | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index a1494f92..234b1034 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1,3 +1,4 @@ +#!/usr/bin/env bash # Copyright (c) 2021-2025 tteck # Author: tteck (tteckster) # Co-Author: MickLesk @@ -30,7 +31,9 @@ fi # This function enables error handling in the script by setting options and defining a trap for the ERR signal. catch_errors() { set -Eeo pipefail - shopt -s errtrace + if [ -n "$BASH_VERSION" ]; then + shopt -s errtrace + fi trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } From 24b5340ed8fc7083048947920ff9c2aaac844477 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 15:07:53 +0200 Subject: [PATCH 411/463] Update build.func --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 234b1034..79e580ef 100644 --- a/misc/build.func +++ b/misc/build.func @@ -31,7 +31,7 @@ fi # This function enables error handling in the script by setting options and defining a trap for the ERR signal. catch_errors() { set -Eeo pipefail - if [ -n "$BASH_VERSION" ]; then + if [ -n "$BASH_VERSION" ] && command -v shopt >/dev/null 2>&1; then shopt -s errtrace fi trap 'error_handler $LINENO "$BASH_COMMAND"' ERR From 8a676cb2a33ca170d8ad3b0f6edfa676489749be Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 15:10:23 +0200 Subject: [PATCH 412/463] Update build.func --- misc/build.func | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/build.func b/misc/build.func index 79e580ef..1e8cd020 100644 --- a/misc/build.func +++ b/misc/build.func @@ -31,9 +31,9 @@ fi # This function enables error handling in the script by setting options and defining a trap for the ERR signal. catch_errors() { set -Eeo pipefail - if [ -n "$BASH_VERSION" ] && command -v shopt >/dev/null 2>&1; then - shopt -s errtrace - fi + # if [ -n "$BASH_VERSION" ] && command -v shopt >/dev/null 2>&1; then + # shopt -s errtrace + # fi trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } From b4eba58f3b36900da2c0be95aa15bc8e1029d789 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 15:16:33 +0200 Subject: [PATCH 413/463] Update build.func --- misc/build.func | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/misc/build.func b/misc/build.func index 1e8cd020..dcd5a73f 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1397,9 +1397,8 @@ EOF' fi msg_ok "Customized LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/"$var_install".sh)" - if [ $? -ne 0 ]; then - exit 100 + if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/"$var_install".sh)"; then + return fi } From f6174a8960c86528a7b3bb88fce3fb51121b13e5 Mon Sep 17 00:00:00 2001 From: tremor021 Date: Mon, 21 Jul 2025 15:18:00 +0200 Subject: [PATCH 414/463] Update Teamspeak --- ct/teamspeak-server.sh | 62 +++++++++++++++++++++++++++++ install/teamspeak-server-install.sh | 55 +++++++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/ct/teamspeak-server.sh b/ct/teamspeak-server.sh index e69de29b..cb0cb4a3 100644 --- a/ct/teamspeak-server.sh +++ b/ct/teamspeak-server.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: tremor021 (Slaviša Arežina) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://teamspeak.com/en/ + +APP="Teamspeak Server" +var_tags="${var_tags:-voice;communication}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-2048}" +var_disk="${var_disk:-4}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +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/teamspeak-server ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | grep -oP 'teamspeak3-server_linux_amd64-\K[0-9]+\.[0-9]+\.[0-9]+' | head -1) + if [[ "${RELEASE}" != "$(cat ~/.teamspeak-server 2>/dev/null)" ]] || [[ ! -f ~/.teamspeak-server ]]; then + msg_info "Stopping Service" + systemctl stop teamspeak-server + msg_ok "Stopped Service" + + msg_info "Updating ${APP}" + curl -fsSL "https://files.teamspeak-services.com/releases/server/${RELEASE}/teamspeak3-server_linux_amd64-${RELEASE}.tar.bz2" -o ts3server.tar.bz2 + tar -xf ./ts3server.tar.bz2 + cp -ru teamspeak3-server_linux_amd64/* /opt/teamspeak-server/ + msg_ok "Updated $APP" + + msg_info "Starting Service" + systemctl start teamspeak-server + msg_ok "Started Service" + + msg_ok "Updated Successfully" + else + msg_ok "Already up to date" + fi + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${ADVANCED}${BL}Create your initial user in${CL} ${BGN}/opt/${APP}${CL}${BL} in the LXC:${CL} ${RD}npm run user:create ${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3002${CL}" diff --git a/install/teamspeak-server-install.sh b/install/teamspeak-server-install.sh index e69de29b..2d6c97e2 100644 --- a/install/teamspeak-server-install.sh +++ b/install/teamspeak-server-install.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: tremor021 (Slaviša Arežina) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://teamspeak.com/en/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | grep -oP 'teamspeak3-server_linux_amd64-\K[0-9]+\.[0-9]+\.[0-9]+' | head -1) + +msg_info "Setting up Teamspeak Server" +curl -fsSL "https://files.teamspeak-services.com/releases/server/${RELEASE}/teamspeak3-server_linux_amd64-${RELEASE}.tar.bz2" -o ts3server.tar.bz2 +tar -xf ./ts3server.tar.bz2 +mv teamspeak3-server_linux_amd64/ /opt/teamspeak-server/ +touch /opt/teamspeak-server/.ts3server_license_accepted +msg_ok "Setup Teamspeak Server" + +msg_info "Creating service" +cat </etc/systemd/system/teamspeak-server.service +[Unit] +Description=TeamSpeak3 Server +Wants=network-online.target +After=network.target + +[Service] +WorkingDirectory=/opt/teamspeak +User=root +Type=forking +ExecStart=/opt/teamspeak-server/ts3server_startscript.sh start +ExecStop=/opt/teamspeak-server/ts3server_startscript.sh stop +ExecReload=/opt/teamspeak-server/ts3server_startscript.sh restart +Restart=always +RestartSec=15 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now teamspeak-server +msg_ok "Created service" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -f ~/ts3server.tar.bz* +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From f4f67d8ea8035025c908cdd6b53064a120c25bcf Mon Sep 17 00:00:00 2001 From: tremor021 Date: Mon, 21 Jul 2025 15:23:56 +0200 Subject: [PATCH 415/463] Update Teamspeak --- ct/teamspeak-server.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/teamspeak-server.sh b/ct/teamspeak-server.sh index cb0cb4a3..50cdee99 100644 --- a/ct/teamspeak-server.sh +++ b/ct/teamspeak-server.sh @@ -5,7 +5,7 @@ source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/ # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE # Source: https://teamspeak.com/en/ -APP="Teamspeak Server" +APP="teamspeak-server" var_tags="${var_tags:-voice;communication}" var_cpu="${var_cpu:-1}" var_ram="${var_ram:-2048}" From c406dcfa99c166b3b72ac4bc093182ca9a2443bf Mon Sep 17 00:00:00 2001 From: tremor021 Date: Mon, 21 Jul 2025 15:32:20 +0200 Subject: [PATCH 416/463] Update Teamspeak --- ct/teamspeak-server.sh | 5 ++--- install/teamspeak-server-install.sh | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/ct/teamspeak-server.sh b/ct/teamspeak-server.sh index 50cdee99..07335920 100644 --- a/ct/teamspeak-server.sh +++ b/ct/teamspeak-server.sh @@ -5,7 +5,7 @@ source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/ # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE # Source: https://teamspeak.com/en/ -APP="teamspeak-server" +APP="Teamspeak-Server" var_tags="${var_tags:-voice;communication}" var_cpu="${var_cpu:-1}" var_ram="${var_ram:-2048}" @@ -57,6 +57,5 @@ description msg_ok "Completed Successfully!\n" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" -echo -e "${ADVANCED}${BL}Create your initial user in${CL} ${BGN}/opt/${APP}${CL}${BL} in the LXC:${CL} ${RD}npm run user:create ${CL}" echo -e "${INFO}${YW} Access it using the following URL:${CL}" -echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3002${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:7100${CL}" diff --git a/install/teamspeak-server-install.sh b/install/teamspeak-server-install.sh index 2d6c97e2..a02e7147 100644 --- a/install/teamspeak-server-install.sh +++ b/install/teamspeak-server-install.sh @@ -30,7 +30,7 @@ Wants=network-online.target After=network.target [Service] -WorkingDirectory=/opt/teamspeak +WorkingDirectory=/opt/teamspeak-server User=root Type=forking ExecStart=/opt/teamspeak-server/ts3server_startscript.sh start From a8c04a319f74f685bf5d9bf799c0c81549332f4f Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 21 Jul 2025 13:32:43 +0000 Subject: [PATCH 417/463] Update .app files --- ct/headers/teamspeak-server | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ct/headers/teamspeak-server diff --git a/ct/headers/teamspeak-server b/ct/headers/teamspeak-server new file mode 100644 index 00000000..92c3a8e4 --- /dev/null +++ b/ct/headers/teamspeak-server @@ -0,0 +1,6 @@ + ______ __ _____ + /_ __/__ ____ _____ ___ _________ ___ ____ _/ /__ / ___/___ ______ _____ _____ + / / / _ \/ __ `/ __ `__ \/ ___/ __ \/ _ \/ __ `/ //_/_____\__ \/ _ \/ ___/ | / / _ \/ ___/ + / / / __/ /_/ / / / / / (__ ) /_/ / __/ /_/ / ,< /_____/__/ / __/ / | |/ / __/ / +/_/ \___/\__,_/_/ /_/ /_/____/ .___/\___/\__,_/_/|_| /____/\___/_/ |___/\___/_/ + /_/ From b6df57617b09c3f9c5938db0a3eb37dec1597c98 Mon Sep 17 00:00:00 2001 From: tremor021 Date: Mon, 21 Jul 2025 15:45:33 +0200 Subject: [PATCH 418/463] Update Teamspeak --- install/teamspeak-server-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/teamspeak-server-install.sh b/install/teamspeak-server-install.sh index a02e7147..8fb45f2c 100644 --- a/install/teamspeak-server-install.sh +++ b/install/teamspeak-server-install.sh @@ -20,6 +20,7 @@ curl -fsSL "https://files.teamspeak-services.com/releases/server/${RELEASE}/team tar -xf ./ts3server.tar.bz2 mv teamspeak3-server_linux_amd64/ /opt/teamspeak-server/ touch /opt/teamspeak-server/.ts3server_license_accepted +echo "${RELEASE}" >~/.teamspeak-server msg_ok "Setup Teamspeak Server" msg_info "Creating service" From 43816d79dc9d22e87b260c7bab2ea487bf57bc07 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 15:46:23 +0200 Subject: [PATCH 419/463] Update build.func --- misc/build.func | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/misc/build.func b/misc/build.func index dcd5a73f..7b51e996 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1390,16 +1390,17 @@ EOF' msg_warn "Skipping timezone setup – zone '$tz' not found in container" fi - pct exec "$CTID" -- bash -c "apt-get update && apt-get install -y sudo curl mc gnupg2" || { + pct exec "$CTID" -- bash -c "$STD apt-get update && $STD apt-get install -y sudo curl mc gnupg2" || { msg_error "apt-get base packages installation failed" exit 1 } fi msg_ok "Customized LXC Container" - if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/"$var_install".sh)"; then - return + if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)"; then + exit $? fi + } # This function sets the description of the container. From 3de63d06f35a74b134731a1420f7305351aea501 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 15:56:18 +0200 Subject: [PATCH 420/463] Update build.func --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 7b51e996..e7dd0796 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1390,7 +1390,7 @@ EOF' msg_warn "Skipping timezone setup – zone '$tz' not found in container" fi - pct exec "$CTID" -- bash -c "$STD apt-get update && $STD apt-get install -y sudo curl mc gnupg2" || { + pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" || { msg_error "apt-get base packages installation failed" exit 1 } From d54281bb875b4a5a60a406edbe77f799873077bb Mon Sep 17 00:00:00 2001 From: tremor021 Date: Mon, 21 Jul 2025 16:03:26 +0200 Subject: [PATCH 421/463] Add Teamspeak json --- ct/teamspeak-server.sh | 6 ++-- frontend/public/json/teamspeak-server.json | 39 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 frontend/public/json/teamspeak-server.json diff --git a/ct/teamspeak-server.sh b/ct/teamspeak-server.sh index 07335920..5f34dd6a 100644 --- a/ct/teamspeak-server.sh +++ b/ct/teamspeak-server.sh @@ -8,8 +8,8 @@ source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/ APP="Teamspeak-Server" var_tags="${var_tags:-voice;communication}" var_cpu="${var_cpu:-1}" -var_ram="${var_ram:-2048}" -var_disk="${var_disk:-4}" +var_ram="${var_ram:-512}" +var_disk="${var_disk:-1}" var_os="${var_os:-debian}" var_version="${var_version:-12}" var_unprivileged="${var_unprivileged:-1}" @@ -58,4 +58,4 @@ 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}:7100${CL}" +echo -e "${TAB}${GATEWAY}${BGN}${IP}:9987${CL}" diff --git a/frontend/public/json/teamspeak-server.json b/frontend/public/json/teamspeak-server.json new file mode 100644 index 00000000..60e8de35 --- /dev/null +++ b/frontend/public/json/teamspeak-server.json @@ -0,0 +1,39 @@ +{ + "name": "Teamspeak Server", + "slug": "teamspeak-server", + "categories": [ + 24 + ], + "date_created": "2025-07-21", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 9987, + "documentation": "https://support.teamspeak.com/hc/en-us/categories/360000302017-TeamSpeak-3", + "website": "https://teamspeak.com/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/teamspeak-light.svgp", + "config_path": "", + "description": "TeamSpeak is a voice‑over‑IP (VoIP) application, primarily used by gamers and teams to chat in real‑time on dedicated servers. It delivers crystal‑clear, low‑latency voice communication.""install_methods": [ + { + "type": "default", + "script": "ct/teamspeak-server.sh", + "resources": { + "cpu": 1, + "ram": 512, + "hdd": 1, + "os": "debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [ + { + "text": "Use `journalctl -u teamspeak-server.service` inside LXC console to check for admin credentials!", + "type": "info" + } + ] +} From 91b21ff24244bd2c3cedd9305774f53db7f80882 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 16:04:14 +0200 Subject: [PATCH 422/463] Update build.func --- misc/build.func | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/misc/build.func b/misc/build.func index e7dd0796..fb60a543 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1397,10 +1397,9 @@ EOF' fi msg_ok "Customized LXC Container" - if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)"; then - exit $? + if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/"$var_install".sh)"; then + return fi - } # This function sets the description of the container. From bf3d258127ea29c72ade825070b95cd85cdabc2c Mon Sep 17 00:00:00 2001 From: tremor021 Date: Mon, 21 Jul 2025 16:12:15 +0200 Subject: [PATCH 423/463] Update Teamspeak --- ct/teamspeak-server.sh | 2 +- frontend/public/json/teamspeak-server.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/teamspeak-server.sh b/ct/teamspeak-server.sh index 5f34dd6a..55f51b85 100644 --- a/ct/teamspeak-server.sh +++ b/ct/teamspeak-server.sh @@ -9,7 +9,7 @@ APP="Teamspeak-Server" var_tags="${var_tags:-voice;communication}" var_cpu="${var_cpu:-1}" var_ram="${var_ram:-512}" -var_disk="${var_disk:-1}" +var_disk="${var_disk:-2}" var_os="${var_os:-debian}" var_version="${var_version:-12}" var_unprivileged="${var_unprivileged:-1}" diff --git a/frontend/public/json/teamspeak-server.json b/frontend/public/json/teamspeak-server.json index 60e8de35..98dbec48 100644 --- a/frontend/public/json/teamspeak-server.json +++ b/frontend/public/json/teamspeak-server.json @@ -20,7 +20,7 @@ "resources": { "cpu": 1, "ram": 512, - "hdd": 1, + "hdd": 2, "os": "debian", "version": "12" } From c927b75da292e5f03f93fa7074bbad2584f7ecd7 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 16:15:10 +0200 Subject: [PATCH 424/463] Update build.func --- misc/build.func | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/misc/build.func b/misc/build.func index fb60a543..1dc9e741 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1341,25 +1341,48 @@ EOF # This starts the container and executes -install.sh msg_info "Starting LXC Container" pct start "$CTID" - msg_ok "Started LXC Container" + + # wait for status 'running' + for i in {1..10}; do + if pct status "$CTID" | grep -q "status: running"; then + msg_ok "Startted LXC Container" + break + fi + sleep 1 + if [ "$i" -eq 10 ]; then + msg_error "LXC Container did not reach running state" + exit 1 + fi + done msg_info "Waiting for network in LXC container" for i in {1..10}; do if pct exec "$CTID" -- ping -c1 -W1 deb.debian.org >/dev/null 2>&1; then msg_ok "Network in LXC is reachable" break - else + fi + if [ "$i" -lt 10 ]; then msg_warn "No network yet in LXC (try $i/10) – waiting..." sleep 3 - fi - if [ $i -eq 10 ]; then - msg_error "No network in LXC after waiting. Setting fallback DNS..." - pct set "$CTID" --nameserver 1.1.1.1 - pct set "$CTID" --nameserver 8.8.8.8 - if ! pct exec "$CTID" -- ping -c1 -W1 deb.debian.org >/dev/null 2>&1; then - msg_error "Still no network/DNS in LXC! Aborting customization." - exit 1 - fi + else + msg_error "No network in LXC after waiting." + read -r -p "Set fallback DNS (1.1.1.1/8.8.8.8)? [y/N]: " choice + case "$choice" in + [yY]*) + pct set "$CTID" --nameserver 1.1.1.1 + pct set "$CTID" --nameserver 8.8.8.8 + if pct exec "$CTID" -- ping -c1 -W1 deb.debian.org >/dev/null 2>&1; then + msg_ok "Network reachable after DNS fallback" + else + msg_error "Still no network/DNS in LXC! Aborting customization." + exit 1 + fi + ;; + *) + msg_error "Aborted by user – no DNS fallback set." + exit 1 + ;; + esac fi done From af0b122bd8748bba2fa1b4a226c2b4264476834c Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 18:33:34 +0200 Subject: [PATCH 425/463] Update rybbit-install.sh --- install/rybbit-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install/rybbit-install.sh b/install/rybbit-install.sh index 4865a0d8..62a825b9 100644 --- a/install/rybbit-install.sh +++ b/install/rybbit-install.sh @@ -32,7 +32,6 @@ msg_info "Setting up PostgreSQL Database" DB_NAME=rybbit_db DB_USER=rybbit DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" -APP_SECRET=$(openssl rand -base64 32) $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" From 8ac6700b9450cd7c14e436f69783e9c89bc05ede Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 18:39:59 +0200 Subject: [PATCH 426/463] Update linkstack-install.sh --- install/linkstack-install.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/install/linkstack-install.sh b/install/linkstack-install.sh index 87e8c14d..f9024516 100644 --- a/install/linkstack-install.sh +++ b/install/linkstack-install.sh @@ -21,15 +21,14 @@ $STD apt-get install -y \ apt-transport-https msg_ok "Installed dependencies" -PHP_VERSION="8.2" PHP_MODULE="sqlite3, mysql, fileinfo" PHP_APACHE="YES" install_php +PHP_VERSION="8.3" PHP_MODULE="sqlite3, mysql, fileinfo" PHP_APACHE="YES" setup_php msg_info "Installing LinkStack" $STD a2enmod rewrite -ZIP_URL="https://github.com/linkstackorg/linkstack/releases/latest/download/linkstack.zip" -ZIP_FILE="/tmp/linkstack.zip" -curl -fsSL -o "$ZIP_FILE" "$ZIP_URL" -unzip -q "$ZIP_FILE" -d /var/www/html/linkstack +fetch_and_deploy_gh_release "linkstack" "linkstackorg/linkstack" "prebuild" "latest" "/var/www/html/linkstack" + +msg_info "Configuring LinkStack" chown -R www-data:www-data /var/www/html/linkstack chmod -R 755 /var/www/html/linkstack @@ -55,7 +54,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD rm -f "$ZIP_FILE" $STD apt-get -y autoremove $STD apt-get -y autoclean msg_ok "Cleaned" From 22c51351fbfdc62a13bc04858e4917fc0e1a38e8 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 19:23:19 +0200 Subject: [PATCH 427/463] Update linkstack-install.sh --- install/linkstack-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/linkstack-install.sh b/install/linkstack-install.sh index f9024516..a5b60fbe 100644 --- a/install/linkstack-install.sh +++ b/install/linkstack-install.sh @@ -21,7 +21,7 @@ $STD apt-get install -y \ apt-transport-https msg_ok "Installed dependencies" -PHP_VERSION="8.3" PHP_MODULE="sqlite3, mysql, fileinfo" PHP_APACHE="YES" setup_php +PHP_VERSION="8.3" PHP_MODULE="sqlite3" PHP_APACHE="YES" setup_php msg_info "Installing LinkStack" $STD a2enmod rewrite From 4b243158bd7b45b850a40894e30b0799a0dda049 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 21 Jul 2025 19:30:17 +0200 Subject: [PATCH 428/463] Update linkstack-install.sh --- install/linkstack-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/linkstack-install.sh b/install/linkstack-install.sh index a5b60fbe..afcd4b02 100644 --- a/install/linkstack-install.sh +++ b/install/linkstack-install.sh @@ -26,7 +26,7 @@ PHP_VERSION="8.3" PHP_MODULE="sqlite3" PHP_APACHE="YES" setup_php msg_info "Installing LinkStack" $STD a2enmod rewrite -fetch_and_deploy_gh_release "linkstack" "linkstackorg/linkstack" "prebuild" "latest" "/var/www/html/linkstack" +fetch_and_deploy_gh_release "linkstack" "linkstackorg/linkstack" "prebuild" "latest" "/var/www/html/linkstack" "linkstack.zip" msg_info "Configuring LinkStack" chown -R www-data:www-data /var/www/html/linkstack From 518c66fc2b22a446b722ccd9576e8a8d024fdfb7 Mon Sep 17 00:00:00 2001 From: tremor021 Date: Mon, 21 Jul 2025 23:21:38 +0200 Subject: [PATCH 429/463] Add Alpine-TeamSpeak --- ct/alpine-teamspeak-server.sh | 57 ++++++++++++++++++ install/alpine-teamspeak-server-install.sh | 69 ++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 ct/alpine-teamspeak-server.sh create mode 100644 install/alpine-teamspeak-server-install.sh diff --git a/ct/alpine-teamspeak-server.sh b/ct/alpine-teamspeak-server.sh new file mode 100644 index 00000000..ed7b0e43 --- /dev/null +++ b/ct/alpine-teamspeak-server.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: Slaviša Arežina (tremor021) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/TwiN/gatus + +APP="Alpine-TeamSpeak-Server" +var_tags="${var_tags:-alpine;communication}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-256}" +var_disk="${var_disk:-2}" +var_os="${var_os:-alpine}" +var_version="${var_version:-3.22}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + + if [[ ! -d /opt/teamspeak-server ]]; then + msg_error "No ${APP} Installation Found!" + exit 1 + fi + + RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | sed -n 's/.*teamspeak3-server_linux_amd64-\([0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p' | head -1) + if [ "${RELEASE}" != "$(cat ~/.teamspeak-server)" ] || [ ! -f ~/.teamspeak-server ]; then + msg_info "Updating ${APP} LXC" + $STD apk -U upgrade + $STD service teamspeak stop + curl -fsSL "https://files.teamspeak-services.com/releases/server/${RELEASE}/teamspeak3-server_linux_amd64-${RELEASE}.tar.bz2" -o ts3server.tar.bz2 + tar -xf ./ts3server.tar.bz2 + cp -ru teamspeak3-server_linux_amd64/* /opt/teamspeak-server/ + rm -f ~/ts3server.tar.bz* + rm -rf teamspeak3-server_linux_amd64 + echo "${RELEASE}" >~/.teamspeak-server + $STD service teamspeak start + msg_ok "Updated Successfully" + else + msg_ok "No update required. ${APP} is already at ${RELEASE}" + fi + + exit 0 +} + +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 IP:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}${IP}:9987${CL}" diff --git a/install/alpine-teamspeak-server-install.sh b/install/alpine-teamspeak-server-install.sh new file mode 100644 index 00000000..e767722b --- /dev/null +++ b/install/alpine-teamspeak-server-install.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: Slaviša Arežina (tremor021) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/TwiN/gatus + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing dependencies" +$STD apk add --no-cache \ + ca-certificates \ + libstdc++ \ + libc6-compat +msg_ok "Installed dependencies" + +RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | sed -n 's/.*teamspeak3-server_linux_amd64-\([0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p' | head -1) + +msg_info "Installing Teamspeak Server v${RELEASE}" +mkdir -p /opt/teamspeak-server +cd /opt/teamspeak-server +curl -fsSL "https://files.teamspeak-services.com/releases/server/${RELEASE}/teamspeak3-server_linux_amd64-${RELEASE}.tar.bz2" -o ts3server.tar.bz2 +tar xf ts3server.tar.bz2 --strip-components=1 +mkdir -p logs data lib +mv *.so lib +touch data/ts3server.sqlitedb data/query_ip_blacklist.txt data/query_ip_whitelist.txt .ts3server_license_accepted +echo "${RELEASE}" >~/.teamspeak-server +msg_ok "Installed TeamSpeak Server v${RELEASE}" + +msg_info "Enabling TeamSpeak Server Service" +cat </etc/init.d/teamspeak +#!/sbin/openrc-run + +name="TeamSpeak Server" +description="TeamSpeak 3 Server" +command="/opt/teamspeak-server/ts3server_startscript.sh" +command_args="start" +output_log="/var/log/teamspeak.out.log" +error_log="/var/log/teamspeak.err.log" +command_background=true +pidfile="/run/teamspeak-server.pid" +directory="/opt/teamspeak-server" + +depend() { + need net + use dns +} +EOF +chmod +x /etc/init.d/teamspeak +$STD rc-update add teamspeak default +msg_ok "Enabled TeamSpeak Server Service" + +msg_info "Starting TeamSpeak Server" +$STD service gatus start +msg_ok "Started TeamSpeak Server" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -r ts3server.tar.bz* LICENSE* CHANGELOG doc serverquerydocs tsdns redist +$STD apk cache clean +msg_ok "Cleaned" From f59b00a1029c71da87464e711a28de5c4e494f8a Mon Sep 17 00:00:00 2001 From: tremor021 Date: Mon, 21 Jul 2025 23:23:35 +0200 Subject: [PATCH 430/463] Update headers --- ct/alpine-teamspeak-server.sh | 4 ++-- install/alpine-teamspeak-server-install.sh | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ct/alpine-teamspeak-server.sh b/ct/alpine-teamspeak-server.sh index ed7b0e43..16bb8048 100644 --- a/ct/alpine-teamspeak-server.sh +++ b/ct/alpine-teamspeak-server.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) # Copyright (c) 2021-2025 community-scripts ORG -# Author: Slaviša Arežina (tremor021) +# Author: tremor021 (Slaviša Arežina) # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/TwiN/gatus +# Source: https://teamspeak.com/en/ APP="Alpine-TeamSpeak-Server" var_tags="${var_tags:-alpine;communication}" diff --git a/install/alpine-teamspeak-server-install.sh b/install/alpine-teamspeak-server-install.sh index e767722b..af311467 100644 --- a/install/alpine-teamspeak-server-install.sh +++ b/install/alpine-teamspeak-server-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash # Copyright (c) 2021-2025 community-scripts ORG -# Author: Slaviša Arežina (tremor021) +# Author: tremor021 (Slaviša Arežina) # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/TwiN/gatus +# Source: https://teamspeak.com/en/ source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color @@ -57,7 +57,7 @@ $STD rc-update add teamspeak default msg_ok "Enabled TeamSpeak Server Service" msg_info "Starting TeamSpeak Server" -$STD service gatus start +$STD service teamspeak start msg_ok "Started TeamSpeak Server" motd_ssh From d962fb4150c624dc9efaf98dc8980507ca9fb882 Mon Sep 17 00:00:00 2001 From: tremor021 Date: Mon, 21 Jul 2025 23:24:44 +0200 Subject: [PATCH 431/463] Update Alpine-TeamSpeak --- ct/alpine-teamspeak-server.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-teamspeak-server.sh b/ct/alpine-teamspeak-server.sh index 16bb8048..1fee6cdc 100644 --- a/ct/alpine-teamspeak-server.sh +++ b/ct/alpine-teamspeak-server.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) # Copyright (c) 2021-2025 community-scripts ORG # Author: tremor021 (Slaviša Arežina) # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE From d346e9042b97488e1984be6bd0e1c04e64892f79 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 21 Jul 2025 21:25:05 +0000 Subject: [PATCH 432/463] Update .app files --- ct/headers/alpine-teamspeak-server | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ct/headers/alpine-teamspeak-server diff --git a/ct/headers/alpine-teamspeak-server b/ct/headers/alpine-teamspeak-server new file mode 100644 index 00000000..cfa5aeb9 --- /dev/null +++ b/ct/headers/alpine-teamspeak-server @@ -0,0 +1,6 @@ + ___ __ _ ______ _____ __ _____ + / | / /___ (_)___ ___ /_ __/__ ____ _____ ___ / ___/____ ___ ____ _/ /__ / ___/___ ______ _____ _____ + / /| | / / __ \/ / __ \/ _ \______/ / / _ \/ __ `/ __ `__ \\__ \/ __ \/ _ \/ __ `/ //_/_____\__ \/ _ \/ ___/ | / / _ \/ ___/ + / ___ |/ / /_/ / / / / / __/_____/ / / __/ /_/ / / / / / /__/ / /_/ / __/ /_/ / ,< /_____/__/ / __/ / | |/ / __/ / +/_/ |_/_/ .___/_/_/ /_/\___/ /_/ \___/\__,_/_/ /_/ /_/____/ .___/\___/\__,_/_/|_| /____/\___/_/ |___/\___/_/ + /_/ /_/ From 49d9984841289aa2d165dac6f19f087e305f4a21 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 09:28:50 +0200 Subject: [PATCH 433/463] finalize --- ct/linkstack.sh | 42 +++++++++++++++++++++++++++++------- install/linkstack-install.sh | 2 +- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/ct/linkstack.sh b/ct/linkstack.sh index 2a88277d..db1ad4ef 100644 --- a/ct/linkstack.sh +++ b/ct/linkstack.sh @@ -23,20 +23,46 @@ function update_script() { header_info check_container_storage check_container_resources - - if [[ ! -d /var ]]; then + + if [[ ! -f /.linkstack ]]; then msg_error "No ${APP} Installation Found!" exit fi - - msg_info "Updating $APP LXC" - $STD apt-get update - $STD apt-get -y upgrade - msg_ok "Updated $APP LXC" - + + RELEASE=$(curl -fsSL https://api.github.com/repos/linkstackorg/linkstack/releases/latest | jq -r '.tag_name | ltrimstr("v")') + if [[ "${RELEASE}" != "$(cat ~/.linkstack 2>/dev/null)" ]] || [[ ! -f ~/.linkstack ]]; then + msg_info "Stopping $APP" + systemctl stop apache2 + msg_ok "Stopped $APP" + + msg_info "Creating Backup" + BACKUP_FILE="/opt/linkstack_backup_$(date +%F).tar.gz" + $STD tar -czf "$BACKUP_FILE" /var/www/html/linkstack + msg_ok "Backup Created" + + PHP_VERSION="8.3" PHP_MODULE="sqlite3" PHP_APACHE="YES" setup_php + fetch_and_deploy_gh_release "linkstack" "linkstackorg/linkstack" "prebuild" "latest" "/var/www/html/linkstack" "linkstack.zip" + + msg_info "Updating $APP to v${RELEASE}" + chown -R www-data:www-data /var/www/html/linkstack + chmod -R 755 /var/www/html/linkstack + msg_ok "Updated $APP to v${RELEASE}" + + msg_info "Starting $APP" + systemctl start linkstack + msg_ok "Started $APP" + + msg_info "Cleaning Up" + rm -rf "$BACKUP_FILE" + msg_ok "Cleanup Completed" + msg_ok "Update Successful" + else + msg_ok "No update required. ${APP} is already at v${RELEASE}" + fi exit } + start build_container description diff --git a/install/linkstack-install.sh b/install/linkstack-install.sh index afcd4b02..72d30386 100644 --- a/install/linkstack-install.sh +++ b/install/linkstack-install.sh @@ -48,7 +48,7 @@ EOF $STD a2dissite 000-default.conf $STD a2ensite linkstack.conf $STD systemctl restart apache2 -msg_ok "Installed LinkStack" +msg_ok "Configured LinkStack" motd_ssh customize From aca09d00dded849d2a4a5bcb1f89c20f431134e3 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 09:30:03 +0200 Subject: [PATCH 434/463] finalize --- ct/linkstack.sh | 4 ++-- install/linkstack-install.sh | 14 ++------------ 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/ct/linkstack.sh b/ct/linkstack.sh index db1ad4ef..da7301b7 100644 --- a/ct/linkstack.sh +++ b/ct/linkstack.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) # Copyright (c) 2021-2025 community-scripts ORG -# Author: Omar Minaya +# Author: Omar Minaya | MickLesk (CanbiZ) # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://linkstack.org/ diff --git a/install/linkstack-install.sh b/install/linkstack-install.sh index 72d30386..48c6b9a6 100644 --- a/install/linkstack-install.sh +++ b/install/linkstack-install.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Copyright (c) 2021-2025 community-scripts ORG -# Author: Omar Minaya +# Author: Omar Minaya | MickLesk (CanbiZ) # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://linkstack.org/ @@ -13,22 +13,12 @@ setting_up_container network_check update_os -msg_info "Installing dependencies" -$STD apt-get install -y \ - software-properties-common \ - ca-certificates \ - lsb-release \ - apt-transport-https -msg_ok "Installed dependencies" PHP_VERSION="8.3" PHP_MODULE="sqlite3" PHP_APACHE="YES" setup_php - -msg_info "Installing LinkStack" -$STD a2enmod rewrite - fetch_and_deploy_gh_release "linkstack" "linkstackorg/linkstack" "prebuild" "latest" "/var/www/html/linkstack" "linkstack.zip" msg_info "Configuring LinkStack" +$STD a2enmod rewrite chown -R www-data:www-data /var/www/html/linkstack chmod -R 755 /var/www/html/linkstack From db0c4495206e986f020cc112bd6022cb3798d8c5 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 09:34:02 +0200 Subject: [PATCH 435/463] fix json --- ct/linkstack.sh | 4 +- frontend/public/json/linkstack.json | 82 ++++++++++++++--------------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/ct/linkstack.sh b/ct/linkstack.sh index da7301b7..2ee0eec4 100644 --- a/ct/linkstack.sh +++ b/ct/linkstack.sh @@ -8,8 +8,8 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV APP="LinkStack" var_tags="${var_tags:-os}" var_cpu="${var_cpu:-1}" -var_ram="${var_ram:-2048}" -var_disk="${var_disk:-10}" +var_ram="${var_ram:-1024}" +var_disk="${var_disk:-5}" var_os="${var_os:-debian}" var_version="${var_version:-12}" var_unprivileged="${var_unprivileged:-1}" diff --git a/frontend/public/json/linkstack.json b/frontend/public/json/linkstack.json index 7c706345..33c6d980 100644 --- a/frontend/public/json/linkstack.json +++ b/frontend/public/json/linkstack.json @@ -1,44 +1,44 @@ { - "name": "LinkStack", - "slug": "linkstack", - "categories": [ - 9 - ], - "date_created": "2025-05-21", - "type": "ct", - "updateable": false, - "privileged": false, - "config_path": "/var/www/html/linkstack/linkstack/.env", - "interface_port": 80, - "documentation": "https://docs.linkstack.org/", - "website": "https://linkstack.org/", - "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/linkstack.webp", - "description": "LinkStack is an open-source, self-hosted alternative to Linktree, allowing users to create a customizable profile page to share multiple links, hosted on their own server.", - "install_methods": [ - { - "type": "default", - "script": "ct/linkstack.sh", - "resources": { - "cpu": 1, - "ram": 2048, - "hdd": 10, - "os": "Debian", - "version": "12" - } - } - ], - "default_credentials": { - "username": null, - "password": null + "name": "LinkStack", + "slug": "linkstack", + "categories": [ + 9 + ], + "date_created": "2025-07-22", + "type": "ct", + "updateable": true, + "privileged": false, + "config_path": "/var/www/html/linkstack/.env", + "interface_port": 80, + "documentation": "https://docs.linkstack.org/", + "website": "https://linkstack.org/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/linkstack.webp", + "description": "LinkStack is an open-source, self-hosted alternative to Linktree, allowing users to create a customizable profile page to share multiple links, hosted on their own server.", + "install_methods": [ + { + "type": "default", + "script": "ct/linkstack.sh", + "resources": { + "cpu": 1, + "ram": 1024, + "hdd": 5, + "os": "Debian", + "version": "12" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [ + { + "text": "LinkStack can be updated via the user interface or with the command `update`.", + "type": "info" }, - "notes": [ - { - "text": "LinkStack can be updated via the user interface.", - "type": "info" - }, - { - "text": "Complete setup via the web interface at http:///. Check installation logs: `cat ~/linkstack-install.log`", - "type": "info" - } - ] + { + "text": "Complete setup via the web interface at http:///. Check installation logs: `cat ~/linkstack-install.log`", + "type": "info" + } + ] } From 8fb912a938938b12b2192b6f4936fff0c2e711de Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 09:34:28 +0200 Subject: [PATCH 436/463] fix path for apache2 --- install/linkstack-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/linkstack-install.sh b/install/linkstack-install.sh index 48c6b9a6..7e87a8a5 100644 --- a/install/linkstack-install.sh +++ b/install/linkstack-install.sh @@ -25,10 +25,10 @@ chmod -R 755 /var/www/html/linkstack cat < /etc/apache2/sites-available/linkstack.conf ServerAdmin webmaster@localhost - DocumentRoot /var/www/html/linkstack/linkstack + DocumentRoot /var/www/html/linkstack ErrorLog /var/log/apache2/linkstack-error.log CustomLog /var/log/apache2/linkstack-access.log combined - + Options Indexes FollowSymLinks AllowOverride All Require all granted From 4c9208507482293ca5676b8f59027a0e3bf88f26 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 09:34:58 +0200 Subject: [PATCH 437/463] Update linkstack.sh --- ct/linkstack.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/linkstack.sh b/ct/linkstack.sh index 2ee0eec4..731033bf 100644 --- a/ct/linkstack.sh +++ b/ct/linkstack.sh @@ -69,5 +69,5 @@ description msg_ok "Completed Successfully!\n" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" -echo -e "${INFO}${YW} Complete setup at:${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}" From 6c74217c191c5ca1c4516dd7d73727ebf8f9ec5c Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 09:37:53 +0200 Subject: [PATCH 438/463] formatting --- .vscode/settings.json | 2 +- misc/build.func | 2115 +++++++++++++++++++++-------------------- 2 files changed, 1061 insertions(+), 1056 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 8f17c7ff..47009d64 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,7 +18,7 @@ "editor.minimap.enabled": false, "terminal.integrated.scrollback": 10000, "[shellscript]": { - "editor.defaultFormatter": "foxundermoon.shell-format", + "editor.defaultFormatter": "mads-hartmann.bash-ide-vscode", "editor.tabSize": 4, "editor.insertSpaces": true, }, diff --git a/misc/build.func b/misc/build.func index 1dc9e741..58805155 100644 --- a/misc/build.func +++ b/misc/build.func @@ -6,211 +6,210 @@ # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE variables() { - NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. - var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. - INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. - PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase - DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call. - METHOD="default" # sets the METHOD variable to "default", used for the API call. - RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable. - CT_TYPE=${var_unprivileged:-$CT_TYPE} + NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. + var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. + INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. + PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase + DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call. + METHOD="default" # sets the METHOD variable to "default", used for the API call. + RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable. + CT_TYPE=${var_unprivileged:-$CT_TYPE} } source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) if command -v curl >/dev/null 2>&1; then - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) - load_functions - #echo "(build.func) Loaded core.func via curl" + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) + load_functions + #echo "(build.func) Loaded core.func via curl" elif command -v wget >/dev/null 2>&1; then - source <(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) - load_functions - #echo "(build.func) Loaded core.func via wget" + source <(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) + load_functions + #echo "(build.func) Loaded core.func via wget" fi # This function enables error handling in the script by setting options and defining a trap for the ERR signal. catch_errors() { - set -Eeo pipefail - # if [ -n "$BASH_VERSION" ] && command -v shopt >/dev/null 2>&1; then - # shopt -s errtrace - # fi - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + set -Eeo pipefail + # if [ -n "$BASH_VERSION" ] && command -v shopt >/dev/null 2>&1; then + # shopt -s errtrace + # fi + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - printf "\e[?25h" - local error_message="[ERROR] in line $line_number: exit code $exit_code: while executing command $command" - post_update_to_api "failed" "$command" - echo -e "\n$error_message\n" - exit "$exit_code" + local exit_code="$?" + local line_number="$1" + local command="$2" + printf "\e[?25h" + local error_message="[ERROR] in line $line_number: exit code $exit_code: while executing command $command" + post_update_to_api "failed" "$command" + echo -e "\n$error_message\n" + exit "$exit_code" - if [[ -n "$CT_ID" ]]; then - read -p "Remove this Container? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - pct stop "$CT_ID" &>/dev/null - pct destroy "$CT_ID" &>/dev/null - msg_ok "Removed this Container" + if [[ -n "$CT_ID" ]]; then + read -p "Remove this Container? " prompt + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + pct stop "$CT_ID" &>/dev/null + pct destroy "$CT_ID" &>/dev/null + msg_ok "Removed this Container" + fi fi - fi } # Check if the shell is using bash shell_check() { - if [[ "$(basename "$SHELL")" != "bash" ]]; then - clear - msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." - echo -e "\nExiting..." - sleep 2 - exit - fi + if [[ "$(basename "$SHELL")" != "bash" ]]; then + clear + msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." + echo -e "\nExiting..." + sleep 2 + exit + fi } # Run as root only root_check() { - if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then - clear - msg_error "Please run this script as root." - echo -e "\nExiting..." - sleep 2 - exit - fi + if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit + fi } # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { - local PVE_VER - PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')" + local PVE_VER + PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')" - # 8 Version Check - if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then - local MINOR="${BASH_REMATCH[1]}" - if (( MINOR < 1 || MINOR > 4 )); then - msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires Proxmox Virtual Environment Version 8.1 – 8.4" - echo -e "Exiting..." - sleep 2 - exit 1 + # 8 Version Check + if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then + local MINOR="${BASH_REMATCH[1]}" + if ((MINOR < 1 || MINOR > 4)); then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires Proxmox Virtual Environment Version 8.1 – 8.4" + echo -e "Exiting..." + sleep 2 + exit 1 + fi + return 0 fi - return 0 - fi - # 9 Beta Version Check - if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then - msg_custom "Detected Proxmox Virtual Environment $PVE_VER – Beta state, use with caution!" - return 0 - fi + # 9 Beta Version Check + if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then + msg_custom "Detected Proxmox Virtual Environment $PVE_VER – Beta state, use with caution!" + return 0 + fi - # All others (unsupported versions) - msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires Proxmox Virtual Environment Version 8.1 – 8.4 or 9.x (Beta)" - echo -e "Exiting..." - sleep 2 - exit 1 + # All others (unsupported versions) + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires Proxmox Virtual Environment Version 8.1 – 8.4 or 9.x (Beta)" + echo -e "Exiting..." + sleep 2 + exit 1 } - # When a node is running tens of containers, it's possible to exceed the kernel's cryptographic key storage allocations. # These are tuneable, so verify if the currently deployment is approaching the limits, advise the user on how to tune the limits, and exit the script. # https://cleveruptime.com/docs/files/proc-key-users | https://docs.kernel.org/security/keys/core.html maxkeys_check() { - # Read kernel parameters - per_user_maxkeys=$(cat /proc/sys/kernel/keys/maxkeys 2>/dev/null || echo 0) - per_user_maxbytes=$(cat /proc/sys/kernel/keys/maxbytes 2>/dev/null || echo 0) + # Read kernel parameters + per_user_maxkeys=$(cat /proc/sys/kernel/keys/maxkeys 2>/dev/null || echo 0) + per_user_maxbytes=$(cat /proc/sys/kernel/keys/maxbytes 2>/dev/null || echo 0) - # Exit if kernel parameters are unavailable - if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then - echo -e "${CROSS}${RD} Error: Unable to read kernel parameters. Ensure proper permissions.${CL}" - exit 1 - fi + # Exit if kernel parameters are unavailable + if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then + echo -e "${CROSS}${RD} Error: Unable to read kernel parameters. Ensure proper permissions.${CL}" + exit 1 + fi - # Fetch key usage for user ID 100000 (typical for containers) - used_lxc_keys=$(awk '/100000:/ {print $2}' /proc/key-users 2>/dev/null || echo 0) - used_lxc_bytes=$(awk '/100000:/ {split($5, a, "/"); print a[1]}' /proc/key-users 2>/dev/null || echo 0) + # Fetch key usage for user ID 100000 (typical for containers) + used_lxc_keys=$(awk '/100000:/ {print $2}' /proc/key-users 2>/dev/null || echo 0) + used_lxc_bytes=$(awk '/100000:/ {split($5, a, "/"); print a[1]}' /proc/key-users 2>/dev/null || echo 0) - # Calculate thresholds and suggested new limits - threshold_keys=$((per_user_maxkeys - 100)) - threshold_bytes=$((per_user_maxbytes - 1000)) - new_limit_keys=$((per_user_maxkeys * 2)) - new_limit_bytes=$((per_user_maxbytes * 2)) + # Calculate thresholds and suggested new limits + threshold_keys=$((per_user_maxkeys - 100)) + threshold_bytes=$((per_user_maxbytes - 1000)) + new_limit_keys=$((per_user_maxkeys * 2)) + new_limit_bytes=$((per_user_maxbytes * 2)) - # Check if key or byte usage is near limits - failure=0 - if [[ "$used_lxc_keys" -gt "$threshold_keys" ]]; then - echo -e "${CROSS}${RD} Warning: Key usage is near the limit (${used_lxc_keys}/${per_user_maxkeys}).${CL}" - echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxkeys=${new_limit_keys}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." - failure=1 - fi - if [[ "$used_lxc_bytes" -gt "$threshold_bytes" ]]; then - echo -e "${CROSS}${RD} Warning: Key byte usage is near the limit (${used_lxc_bytes}/${per_user_maxbytes}).${CL}" - echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxbytes=${new_limit_bytes}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." - failure=1 - fi + # Check if key or byte usage is near limits + failure=0 + if [[ "$used_lxc_keys" -gt "$threshold_keys" ]]; then + echo -e "${CROSS}${RD} Warning: Key usage is near the limit (${used_lxc_keys}/${per_user_maxkeys}).${CL}" + echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxkeys=${new_limit_keys}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." + failure=1 + fi + if [[ "$used_lxc_bytes" -gt "$threshold_bytes" ]]; then + echo -e "${CROSS}${RD} Warning: Key byte usage is near the limit (${used_lxc_bytes}/${per_user_maxbytes}).${CL}" + echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxbytes=${new_limit_bytes}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." + failure=1 + fi - # Provide next steps if issues are detected - if [[ "$failure" -eq 1 ]]; then - echo -e "${INFO} To apply changes, run: ${BOLD}service procps force-reload${CL}" - exit 1 - fi + # Provide next steps if issues are detected + if [[ "$failure" -eq 1 ]]; then + echo -e "${INFO} To apply changes, run: ${BOLD}service procps force-reload${CL}" + exit 1 + fi - echo -e "${CM}${GN} All kernel key limits are within safe thresholds.${CL}" + echo -e "${CM}${GN} All kernel key limits are within safe thresholds.${CL}" } # This function checks the system architecture and exits if it's not "amd64". arch_check() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n" - echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" - echo -e "Exiting..." - sleep 2 - exit - fi + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n" + echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" + echo -e "Exiting..." + sleep 2 + exit + fi } # Function to get the current IP address based on the distribution get_current_ip() { - if [ -f /etc/os-release ]; then - # Check for Debian/Ubuntu (uses hostname -I) - if grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then - CURRENT_IP=$(hostname -I | awk '{print $1}') - # Check for Alpine (uses ip command) - elif grep -q 'ID=alpine' /etc/os-release; then - CURRENT_IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) - else - CURRENT_IP="Unknown" + if [ -f /etc/os-release ]; then + # Check for Debian/Ubuntu (uses hostname -I) + if grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then + CURRENT_IP=$(hostname -I | awk '{print $1}') + # Check for Alpine (uses ip command) + elif grep -q 'ID=alpine' /etc/os-release; then + CURRENT_IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) + else + CURRENT_IP="Unknown" + fi fi - fi - echo "$CURRENT_IP" + echo "$CURRENT_IP" } # Function to update the IP address in the MOTD file update_motd_ip() { - MOTD_FILE="/etc/motd" + MOTD_FILE="/etc/motd" - if [ -f "$MOTD_FILE" ]; then - # Remove existing IP Address lines to prevent duplication - sed -i '/IP Address:/d' "$MOTD_FILE" + if [ -f "$MOTD_FILE" ]; then + # Remove existing IP Address lines to prevent duplication + sed -i '/IP Address:/d' "$MOTD_FILE" - IP=$(get_current_ip) - # Add the new IP address - echo -e "${TAB}${NETWORK}${YW} IP Address: ${GN}${IP}${CL}" >>"$MOTD_FILE" - fi + IP=$(get_current_ip) + # Add the new IP address + echo -e "${TAB}${NETWORK}${YW} IP Address: ${GN}${IP}${CL}" >>"$MOTD_FILE" + fi } # This function checks if the script is running through SSH and prompts the user to confirm if they want to proceed or exit. ssh_check() { - if [ -n "${SSH_CLIENT:+x}" ]; then - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's advisable to utilize the Proxmox shell rather than SSH, as there may be potential complications with variable retrieval. Proceed using SSH?" 10 72; then - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Proceed using SSH" "You've chosen to proceed using SSH. If any issues arise, please run the script in the Proxmox shell before creating a repository issue." 10 72 - else - clear - echo "Exiting due to SSH usage. Please consider using the Proxmox shell." - exit + if [ -n "${SSH_CLIENT:+x}" ]; then + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's advisable to utilize the Proxmox shell rather than SSH, as there may be potential complications with variable retrieval. Proceed using SSH?" 10 72; then + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Proceed using SSH" "You've chosen to proceed using SSH. If any issues arise, please run the script in the Proxmox shell before creating a repository issue." 10 72 + else + clear + echo "Exiting due to SSH usage. Please consider using the Proxmox shell." + exit + fi fi - fi } # select_storage() { @@ -301,62 +300,62 @@ ssh_check() { # } base_settings() { - # Default Settings - CT_TYPE="1" - DISK_SIZE="4" - CORE_COUNT="1" - RAM_SIZE="1024" - VERBOSE="${1:-no}" - PW="" - CT_ID=$NEXTID - HN=$NSAPP - BRG="vmbr0" - NET="dhcp" - IPV6_METHOD="none" - IPV6_STATIC="" - GATE="" - APT_CACHER="" - APT_CACHER_IP="" - #DISABLEIP6="no" - MTU="" - SD="" - NS="" - MAC="" - VLAN="" - SSH="no" - SSH_AUTHORIZED_KEY="" - UDHCPC_FIX="" - TAGS="community-script;" - ENABLE_FUSE="${1:-no}" - ENABLE_TUN="${1:-no}" + # Default Settings + CT_TYPE="1" + DISK_SIZE="4" + CORE_COUNT="1" + RAM_SIZE="1024" + VERBOSE="${1:-no}" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + BRG="vmbr0" + NET="dhcp" + IPV6_METHOD="none" + IPV6_STATIC="" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + #DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + SSH_AUTHORIZED_KEY="" + UDHCPC_FIX="" + TAGS="community-script;" + ENABLE_FUSE="${1:-no}" + ENABLE_TUN="${1:-no}" - # Override default settings with variables from ct script - CT_TYPE=${var_unprivileged:-$CT_TYPE} - DISK_SIZE=${var_disk:-$DISK_SIZE} - CORE_COUNT=${var_cpu:-$CORE_COUNT} - RAM_SIZE=${var_ram:-$RAM_SIZE} - VERB=${var_verbose:-$VERBOSE} - TAGS="${TAGS}${var_tags:-}" - ENABLE_FUSE="${var_fuse:-$ENABLE_FUSE}" - ENABLE_TUN="${var_tun:-$ENABLE_TUN}" - APT_CACHER="${var_apt_cacher:-$APT_CACHER}" - APT_CACHER_IP="${var_apt_cacher_ip:-$APT_CACHER_IP}" + # Override default settings with variables from ct script + CT_TYPE=${var_unprivileged:-$CT_TYPE} + DISK_SIZE=${var_disk:-$DISK_SIZE} + CORE_COUNT=${var_cpu:-$CORE_COUNT} + RAM_SIZE=${var_ram:-$RAM_SIZE} + VERB=${var_verbose:-$VERBOSE} + TAGS="${TAGS}${var_tags:-}" + ENABLE_FUSE="${var_fuse:-$ENABLE_FUSE}" + ENABLE_TUN="${var_tun:-$ENABLE_TUN}" + APT_CACHER="${var_apt_cacher:-$APT_CACHER}" + APT_CACHER_IP="${var_apt_cacher_ip:-$APT_CACHER_IP}" - # Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts - if [ -z "$var_os" ]; then - var_os="debian" - fi - if [ -z "$var_version" ]; then - var_version="12" - fi + # Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts + if [ -z "$var_os" ]; then + var_os="debian" + fi + if [ -z "$var_version" ]; then + var_version="12" + fi } write_config() { - mkdir -p /opt/community-scripts - # This function writes the configuration to a file. - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Write configfile" --yesno "Do you want to write the selections to a config file?" 10 60; then - FILEPATH="/opt/community-scripts/${NSAPP}.conf" - if [[ ! -f $FILEPATH ]]; then - cat <"$FILEPATH" + mkdir -p /opt/community-scripts + # This function writes the configuration to a file. + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Write configfile" --yesno "Do you want to write the selections to a config file?" 10 60; then + FILEPATH="/opt/community-scripts/${NSAPP}.conf" + if [[ ! -f $FILEPATH ]]; then + cat <"$FILEPATH" # ${NSAPP} Configuration File # Generated on $(date) @@ -383,12 +382,12 @@ NET="${NET}" FUSE="${ENABLE_FUSE}" EOF - echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" - else - echo -e "${INFO}${BOLD}${RD}Configuration file already exists at ${FILEPATH}${CL}" - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Overwrite configfile" --yesno "Do you want to overwrite the existing config file?" 10 60; then - rm -f "$FILEPATH" - cat <"$FILEPATH" + echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" + else + echo -e "${INFO}${BOLD}${RD}Configuration file already exists at ${FILEPATH}${CL}" + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Overwrite configfile" --yesno "Do you want to overwrite the existing config file?" 10 60; then + rm -f "$FILEPATH" + cat <"$FILEPATH" # ${NSAPP} Configuration File # Generated on $(date) @@ -415,518 +414,518 @@ NET="${NET}" FUSE="${ENABLE_FUSE}" EOF - echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" - else - echo -e "${INFO}${BOLD}${RD}Configuration file not overwritten${CL}" - fi + echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" + else + echo -e "${INFO}${BOLD}${RD}Configuration file not overwritten${CL}" + fi + fi fi - fi } # This function displays the default values for various settings. echo_default() { - # Convert CT_TYPE to description - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi + # Convert CT_TYPE to description + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi - # Output the selected values with icons - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os ($var_version)${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" - echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - if [ "$VERB" == "yes" ]; then - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}" - fi - echo -e "${CREATING}${BOLD}${BL}Creating a ${APP} LXC using the above default settings${CL}" - echo -e " " + # Output the selected values with icons + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os ($var_version)${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" + echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" + echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" + if [ "$VERB" == "yes" ]; then + echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}" + fi + echo -e "${CREATING}${BOLD}${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e " " } # This function is called when the user decides to exit the script. It clears the screen and displays an exit message. exit_script() { - clear - echo -e "\n${CROSS}${RD}User exited script${CL}\n" - exit + clear + echo -e "\n${CROSS}${RD}User exited script${CL}\n" + exit } # This function allows the user to configure advanced settings for the script. advanced_settings() { - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 - # Setting Default Tag for Advanced Settings - TAGS="community-script;${var_tags:-}" - CT_DEFAULT_TYPE="${CT_TYPE}" - CT_TYPE="" - while [ -z "$CT_TYPE" ]; do - if [ "$CT_DEFAULT_TYPE" == "1" ]; then - if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - if [ -n "$CT_TYPE" ]; then - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os | ${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 + # Setting Default Tag for Advanced Settings + TAGS="community-script;${var_tags:-}" + CT_DEFAULT_TYPE="${CT_TYPE}" + CT_TYPE="" + while [ -z "$CT_TYPE" ]; do + if [ "$CT_DEFAULT_TYPE" == "1" ]; then + if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then + if [ -n "$CT_TYPE" ]; then + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os | ${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" + fi + else + exit_script + fi fi - else + if [ "$CT_DEFAULT_TYPE" == "0" ]; then + if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3); then + if [ -n "$CT_TYPE" ]; then + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" + echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" + fi + else + exit_script + fi + fi + done + + while true; do + if PW1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD (leave blank for automatic login)" 3>&1 1>&2 2>&3); then + # Empty = Autologin + if [[ -z "$PW1" ]]; then + PW="" + PW1="Automatic Login" + echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}$PW1${CL}" + break + fi + + # Invalid: contains spaces + if [[ "$PW1" == *" "* ]]; then + whiptail --msgbox "Password cannot contain spaces." 8 58 + continue + fi + + # Invalid: too short + if ((${#PW1} < 5)); then + whiptail --msgbox "Password must be at least 5 characters." 8 58 + continue + fi + + # Confirm password + if PW2=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nVerify Root Password" 9 58 --title "PASSWORD VERIFICATION" 3>&1 1>&2 2>&3); then + if [[ "$PW1" == "$PW2" ]]; then + PW="-password $PW1" + echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}********${CL}" + break + else + whiptail --msgbox "Passwords do not match. Please try again." 8 58 + fi + else + exit_script + fi + else + exit_script + fi + done + + if CT_ID=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 "$NEXTID" --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi + else exit_script - fi fi - if [ "$CT_DEFAULT_TYPE" == "0" ]; then - if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3); then - if [ -n "$CT_TYPE" ]; then - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" + + while true; do + if CT_NAME=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 "$NSAPP" --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo "${CT_NAME,,}" | tr -d ' ') + fi + # Hostname validate (RFC 1123) + if [[ "$HN" =~ ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ ]]; then + echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}" + break + else + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --msgbox "❌ Invalid hostname: '$HN'\n\nOnly lowercase letters, digits and hyphens (-) are allowed.\nUnderscores (_) or other characters are not permitted!" 10 70 + fi + else + exit_script fi - else + done + + while true; do + DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GB" 8 58 "$var_disk" --title "DISK SIZE" 3>&1 1>&2 2>&3) || exit_script + + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + fi + + if [[ "$DISK_SIZE" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" + break + else + whiptail --msgbox "Disk size must be a positive integer!" 8 58 + fi + done + + while true; do + CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ + --inputbox "Allocate CPU Cores" 8 58 "$var_cpu" --title "CORE COUNT" 3>&1 1>&2 2>&3) || exit_script + + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + fi + + if [[ "$CORE_COUNT" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}" + break + else + whiptail --msgbox "CPU core count must be a positive integer!" 8 58 + fi + done + + while true; do + RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ + --inputbox "Allocate RAM in MiB" 8 58 "$var_ram" --title "RAM" 3>&1 1>&2 2>&3) || exit_script + + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + fi + + if [[ "$RAM_SIZE" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" + break + else + whiptail --msgbox "RAM size must be a positive integer!" 8 58 + fi + done + + IFACE_FILEPATH_LIST="/etc/network/interfaces"$'\n'$(find "/etc/network/interfaces.d/" -type f) + BRIDGES="" + OLD_IFS=$IFS + IFS=$'\n' + for iface_filepath in ${IFACE_FILEPATH_LIST}; do + + iface_indexes_tmpfile=$(mktemp -q -u '.iface-XXXX') + (grep -Pn '^\s*iface' "${iface_filepath}" | cut -d':' -f1 && wc -l "${iface_filepath}" | cut -d' ' -f1) | awk 'FNR==1 {line=$0; next} {print line":"$0-1; line=$0}' >"${iface_indexes_tmpfile}" || true + + if [ -f "${iface_indexes_tmpfile}" ]; then + + while read -r pair; do + start=$(echo "${pair}" | cut -d':' -f1) + end=$(echo "${pair}" | cut -d':' -f2) + + if awk "NR >= ${start} && NR <= ${end}" "${iface_filepath}" | grep -qP '^\s*(bridge[-_](ports|stp|fd|vlan-aware|vids)|ovs_type\s+OVSBridge)\b'; then + iface_name=$(sed "${start}q;d" "${iface_filepath}" | awk '{print $2}') + BRIDGES="${iface_name}"$'\n'"${BRIDGES}" + fi + + done <"${iface_indexes_tmpfile}" + rm -f "${iface_indexes_tmpfile}" + fi + + done + IFS=$OLD_IFS + BRIDGES=$(echo "$BRIDGES" | grep -v '^\s*$' | sort | uniq) + if [[ -z "$BRIDGES" ]]; then + BRG="vmbr0" + echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" + else + BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --menu "Select network bridge:" 15 40 6 $(echo "$BRIDGES" | awk '{print $0, "Bridge"}') 3>&1 1>&2 2>&3) + if [[ -z "$BRG" ]]; then + exit_script + else + echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" + fi + fi + + # IPv4 methods: dhcp, static, none + while true; do + IPV4_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --title "IPv4 Address Management" \ + --menu "Select IPv4 Address Assignment Method:" 12 60 2 \ + "dhcp" "Automatic (DHCP, recommended)" \ + "static" "Static (manual entry)" \ + 3>&1 1>&2 2>&3) + + exit_status=$? + if [ $exit_status -ne 0 ]; then + exit_script + fi + + case "$IPV4_METHOD" in + dhcp) + NET="dhcp" + GATE="" + echo -e "${NETWORK}${BOLD}${DGN}IPv4: DHCP${CL}" + break + ;; + static) + # Static: call and validate CIDR address + while true; do + NET=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --inputbox "Enter Static IPv4 CIDR Address (e.g. 192.168.100.50/24)" 8 58 "" \ + --title "IPv4 ADDRESS" 3>&1 1>&2 2>&3) + if [ -z "$NET" ]; then + whiptail --msgbox "IPv4 address must not be empty." 8 58 + continue + elif [[ "$NET" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then + echo -e "${NETWORK}${BOLD}${DGN}IPv4 Address: ${BGN}$NET${CL}" + break + else + whiptail --msgbox "$NET is not a valid IPv4 CIDR address. Please enter a correct value!" 8 58 + fi + done + + # call and validate Gateway + while true; do + GATE1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --inputbox "Enter Gateway IP address for static IPv4" 8 58 "" \ + --title "Gateway IP" 3>&1 1>&2 2>&3) + if [ -z "$GATE1" ]; then + whiptail --msgbox "Gateway IP address cannot be empty." 8 58 + elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + whiptail --msgbox "Invalid Gateway IP address format." 8 58 + else + GATE=",gw=$GATE1" + echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}$GATE1${CL}" + break + fi + done + break + ;; + esac + done + + # IPv6 Address Management selection + while true; do + IPV6_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --menu \ + "Select IPv6 Address Management Type:" 15 58 4 \ + "auto" "SLAAC/AUTO (recommended, default)" \ + "dhcp" "DHCPv6" \ + "static" "Static (manual entry)" \ + "none" "Disabled" \ + --default-item "auto" 3>&1 1>&2 2>&3) + [ $? -ne 0 ] && exit_script + + case "$IPV6_METHOD" in + auto) + echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}SLAAC/AUTO${CL}" + IPV6_ADDR="" + IPV6_GATE="" + break + ;; + dhcp) + echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}DHCPv6${CL}" + IPV6_ADDR="dhcp" + IPV6_GATE="" + break + ;; + static) + # Ask for static IPv6 address (CIDR notation, e.g., 2001:db8::1234/64) + while true; do + IPV6_ADDR=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ + "Set a static IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 "" \ + --title "IPv6 STATIC ADDRESS" 3>&1 1>&2 2>&3) || exit_script + if [[ "$IPV6_ADDR" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+(/[0-9]{1,3})$ ]]; then + echo -e "${NETWORK}${BOLD}${DGN}IPv6 Address: ${BGN}$IPV6_ADDR${CL}" + break + else + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ + "$IPV6_ADDR is an invalid IPv6 CIDR address. Please enter a valid IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 + fi + done + # Optional: ask for IPv6 gateway for static config + while true; do + IPV6_GATE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ + "Enter IPv6 gateway address (optional, leave blank for none)" 8 58 "" --title "IPv6 GATEWAY" 3>&1 1>&2 2>&3) + if [ -z "$IPV6_GATE" ]; then + IPV6_GATE="" + break + elif [[ "$IPV6_GATE" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+$ ]]; then + break + else + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ + "Invalid IPv6 gateway format." 8 58 + fi + done + break + ;; + none) + echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}Disabled${CL}" + IPV6_ADDR="none" + IPV6_GATE="" + break + ;; + *) + exit_script + ;; + esac + done + + if [ "$var_os" == "alpine" ]; then + APT_CACHER="" + APT_CACHER_IP="" + else + if APT_CACHER_IP=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for none)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then + APT_CACHER="${APT_CACHER_IP:+yes}" + echo -e "${NETWORK}${BOLD}${DGN}APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" + else + exit_script + fi + fi + + # if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + # DISABLEIP6="yes" + # else + # DISABLEIP6="no" + # fi + # echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + + if MTU1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default [The MTU of your selected vmbr, default is 1500])" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$MTU1" ]; then + MTU1="Default" + MTU="" + else + MTU=",mtu=$MTU1" + fi + echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}" + else exit_script - fi fi - done - while true; do - if PW1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD (leave blank for automatic login)" 3>&1 1>&2 2>&3); then - # Empty = Autologin - if [[ -z "$PW1" ]]; then - PW="" - PW1="Automatic Login" - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}$PW1${CL}" - break - fi - - # Invalid: contains spaces - if [[ "$PW1" == *" "* ]]; then - whiptail --msgbox "Password cannot contain spaces." 8 58 - continue - fi - - # Invalid: too short - if ((${#PW1} < 5)); then - whiptail --msgbox "Password must be at least 5 characters." 8 58 - continue - fi - - # Confirm password - if PW2=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nVerify Root Password" 9 58 --title "PASSWORD VERIFICATION" 3>&1 1>&2 2>&3); then - if [[ "$PW1" == "$PW2" ]]; then - PW="-password $PW1" - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}********${CL}" - break + if SD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then + if [ -z "$SD" ]; then + SX=Host + SD="" else - whiptail --msgbox "Passwords do not match. Please try again." 8 58 + SX=$SD + SD="-searchdomain=$SD" fi - else + echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}$SX${CL}" + else exit_script - fi - else - exit_script - fi - done - - if CT_ID=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 "$NEXTID" --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi - else - exit_script - fi - - while true; do - if CT_NAME=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 "$NSAPP" --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo "${CT_NAME,,}" | tr -d ' ') - fi - # Hostname validate (RFC 1123) - if [[ "$HN" =~ ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ ]]; then - echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}" - break - else - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --msgbox "❌ Invalid hostname: '$HN'\n\nOnly lowercase letters, digits and hyphens (-) are allowed.\nUnderscores (_) or other characters are not permitted!" 10 70 - fi - else - exit_script - fi - done - - while true; do - DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GB" 8 58 "$var_disk" --title "DISK SIZE" 3>&1 1>&2 2>&3) || exit_script - - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" fi - if [[ "$DISK_SIZE" =~ ^[1-9][0-9]*$ ]]; then - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" - break - else - whiptail --msgbox "Disk size must be a positive integer!" 8 58 - fi - done - - while true; do - CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ - --inputbox "Allocate CPU Cores" 8 58 "$var_cpu" --title "CORE COUNT" 3>&1 1>&2 2>&3) || exit_script - - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - fi - - if [[ "$CORE_COUNT" =~ ^[1-9][0-9]*$ ]]; then - echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}" - break - else - whiptail --msgbox "CPU core count must be a positive integer!" 8 58 - fi - done - - while true; do - RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ - --inputbox "Allocate RAM in MiB" 8 58 "$var_ram" --title "RAM" 3>&1 1>&2 2>&3) || exit_script - - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - fi - - if [[ "$RAM_SIZE" =~ ^[1-9][0-9]*$ ]]; then - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - break - else - whiptail --msgbox "RAM size must be a positive integer!" 8 58 - fi - done - - IFACE_FILEPATH_LIST="/etc/network/interfaces"$'\n'$(find "/etc/network/interfaces.d/" -type f) - BRIDGES="" - OLD_IFS=$IFS - IFS=$'\n' - for iface_filepath in ${IFACE_FILEPATH_LIST}; do - - iface_indexes_tmpfile=$(mktemp -q -u '.iface-XXXX') - (grep -Pn '^\s*iface' "${iface_filepath}" | cut -d':' -f1 && wc -l "${iface_filepath}" | cut -d' ' -f1) | awk 'FNR==1 {line=$0; next} {print line":"$0-1; line=$0}' >"${iface_indexes_tmpfile}" || true - - if [ -f "${iface_indexes_tmpfile}" ]; then - - while read -r pair; do - start=$(echo "${pair}" | cut -d':' -f1) - end=$(echo "${pair}" | cut -d':' -f2) - - if awk "NR >= ${start} && NR <= ${end}" "${iface_filepath}" | grep -qP '^\s*(bridge[-_](ports|stp|fd|vlan-aware|vids)|ovs_type\s+OVSBridge)\b'; then - iface_name=$(sed "${start}q;d" "${iface_filepath}" | awk '{print $2}') - BRIDGES="${iface_name}"$'\n'"${BRIDGES}" - fi - - done <"${iface_indexes_tmpfile}" - rm -f "${iface_indexes_tmpfile}" - fi - - done - IFS=$OLD_IFS - BRIDGES=$(echo "$BRIDGES" | grep -v '^\s*$' | sort | uniq) - if [[ -z "$BRIDGES" ]]; then - BRG="vmbr0" - echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" - else - BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --menu "Select network bridge:" 15 40 6 $(echo "$BRIDGES" | awk '{print $0, "Bridge"}') 3>&1 1>&2 2>&3) - if [[ -z "$BRG" ]]; then - exit_script - else - echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" - fi - fi - - # IPv4 methods: dhcp, static, none - while true; do - IPV4_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --title "IPv4 Address Management" \ - --menu "Select IPv4 Address Assignment Method:" 12 60 2 \ - "dhcp" "Automatic (DHCP, recommended)" \ - "static" "Static (manual entry)" \ - 3>&1 1>&2 2>&3) - - exit_status=$? - if [ $exit_status -ne 0 ]; then - exit_script - fi - - case "$IPV4_METHOD" in - dhcp) - NET="dhcp" - GATE="" - echo -e "${NETWORK}${BOLD}${DGN}IPv4: DHCP${CL}" - break - ;; - static) - # Static: call and validate CIDR address - while true; do - NET=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --inputbox "Enter Static IPv4 CIDR Address (e.g. 192.168.100.50/24)" 8 58 "" \ - --title "IPv4 ADDRESS" 3>&1 1>&2 2>&3) - if [ -z "$NET" ]; then - whiptail --msgbox "IPv4 address must not be empty." 8 58 - continue - elif [[ "$NET" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then - echo -e "${NETWORK}${BOLD}${DGN}IPv4 Address: ${BGN}$NET${CL}" - break + if NX=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z "$NX" ]; then + NX=Host + NS="" else - whiptail --msgbox "$NET is not a valid IPv4 CIDR address. Please enter a correct value!" 8 58 + NS="-nameserver=$NX" fi - done + echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}$NX${CL}" + else + exit_script + fi - # call and validate Gateway - while true; do - GATE1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --inputbox "Enter Gateway IP address for static IPv4" 8 58 "" \ - --title "Gateway IP" 3>&1 1>&2 2>&3) - if [ -z "$GATE1" ]; then - whiptail --msgbox "Gateway IP address cannot be empty." 8 58 - elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then - whiptail --msgbox "Invalid Gateway IP address format." 8 58 + if [ "$var_os" == "alpine" ] && [ "$NET" == "dhcp" ] && [ "$NX" != "Host" ]; then + UDHCPC_FIX="yes" + else + UDHCPC_FIX="no" + fi + export UDHCPC_FIX + + if MAC1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a MAC Address(leave blank for generated MAC)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z "$MAC1" ]; then + MAC1="Default" + MAC="" else - GATE=",gw=$GATE1" - echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}$GATE1${CL}" - break + MAC=",hwaddr=$MAC1" + echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}" fi - done - break - ;; - esac - done + else + exit_script + fi - # IPv6 Address Management selection - while true; do - IPV6_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --menu \ - "Select IPv6 Address Management Type:" 15 58 4 \ - "auto" "SLAAC/AUTO (recommended, default)" \ - "dhcp" "DHCPv6" \ - "static" "Static (manual entry)" \ - "none" "Disabled" \ - --default-item "auto" 3>&1 1>&2 2>&3) - [ $? -ne 0 ] && exit_script - - case "$IPV6_METHOD" in - auto) - echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}SLAAC/AUTO${CL}" - IPV6_ADDR="" - IPV6_GATE="" - break - ;; - dhcp) - echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}DHCPv6${CL}" - IPV6_ADDR="dhcp" - IPV6_GATE="" - break - ;; - static) - # Ask for static IPv6 address (CIDR notation, e.g., 2001:db8::1234/64) - while true; do - IPV6_ADDR=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ - "Set a static IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 "" \ - --title "IPv6 STATIC ADDRESS" 3>&1 1>&2 2>&3) || exit_script - if [[ "$IPV6_ADDR" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+(/[0-9]{1,3})$ ]]; then - echo -e "${NETWORK}${BOLD}${DGN}IPv6 Address: ${BGN}$IPV6_ADDR${CL}" - break + if VLAN1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for no VLAN)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then + if [ -z "$VLAN1" ]; then + VLAN1="Default" + VLAN="" else - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ - "$IPV6_ADDR is an invalid IPv6 CIDR address. Please enter a valid IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 + VLAN=",tag=$VLAN1" fi - done - # Optional: ask for IPv6 gateway for static config - while true; do - IPV6_GATE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ - "Enter IPv6 gateway address (optional, leave blank for none)" 8 58 "" --title "IPv6 GATEWAY" 3>&1 1>&2 2>&3) - if [ -z "$IPV6_GATE" ]; then - IPV6_GATE="" - break - elif [[ "$IPV6_GATE" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+$ ]]; then - break + echo -e "${VLANTAG}${BOLD}${DGN}Vlan: ${BGN}$VLAN1${CL}" + else + exit_script + fi + + if ADV_TAGS=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Custom Tags?[If you remove all, there will be no tags!]" 8 58 "${TAGS}" --title "Advanced Tags" 3>&1 1>&2 2>&3); then + if [ -n "${ADV_TAGS}" ]; then + ADV_TAGS=$(echo "$ADV_TAGS" | tr -d '[:space:]') + TAGS="${ADV_TAGS}" else - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ - "Invalid IPv6 gateway format." 8 58 + TAGS=";" fi - done - break - ;; - none) - echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}Disabled${CL}" - IPV6_ADDR="none" - IPV6_GATE="" - break - ;; - *) - exit_script - ;; - esac - done - - if [ "$var_os" == "alpine" ]; then - APT_CACHER="" - APT_CACHER_IP="" - else - if APT_CACHER_IP=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for none)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then - APT_CACHER="${APT_CACHER_IP:+yes}" - echo -e "${NETWORK}${BOLD}${DGN}APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" + echo -e "${NETWORK}${BOLD}${DGN}Tags: ${BGN}$TAGS${CL}" else - exit_script + exit_script fi - fi - # if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - # DISABLEIP6="yes" - # else - # DISABLEIP6="no" - # fi - # echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "SSH Authorized key for root (leave empty for none)" 8 58 --title "SSH Key" 3>&1 1>&2 2>&3)" - if MTU1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default [The MTU of your selected vmbr, default is 1500])" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$MTU1" ]; then - MTU1="Default" - MTU="" + if [[ -z "${SSH_AUTHORIZED_KEY}" ]]; then + SSH_AUTHORIZED_KEY="" + fi + + if [[ "$PW" == -password* || -n "$SSH_AUTHORIZED_KEY" ]]; then + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" + else + SSH="no" + fi + echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" else - MTU=",mtu=$MTU1" + SSH="no" + echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" fi - echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}" - else - exit_script - fi - if SD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z "$SD" ]; then - SX=Host - SD="" + if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "FUSE Support" --yesno "Enable FUSE support?\nRequired for tools like rclone, mergerfs, AppImage, etc." 10 58); then + ENABLE_FUSE="yes" else - SX=$SD - SD="-searchdomain=$SD" + ENABLE_FUSE="no" fi - echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}$SX${CL}" - else - exit_script - fi + echo -e "${FUSE}${BOLD}${DGN}Enable FUSE Support: ${BGN}$ENABLE_FUSE${CL}" - if NX=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z "$NX" ]; then - NX=Host - NS="" + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERBOSE="yes" else - NS="-nameserver=$NX" + VERBOSE="no" fi - echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}$NX${CL}" - else - exit_script - fi + echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERBOSE${CL}" - if [ "$var_os" == "alpine" ] && [ "$NET" == "dhcp" ] && [ "$NX" != "Host" ]; then - UDHCPC_FIX="yes" - else - UDHCPC_FIX="no" - fi - export UDHCPC_FIX - - if MAC1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a MAC Address(leave blank for generated MAC)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z "$MAC1" ]; then - MAC1="Default" - MAC="" + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + write_config else - MAC=",hwaddr=$MAC1" - echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}" + clear + header_info + echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" + advanced_settings fi - else - exit_script - fi - - if VLAN1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for no VLAN)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z "$VLAN1" ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${VLANTAG}${BOLD}${DGN}Vlan: ${BGN}$VLAN1${CL}" - else - exit_script - fi - - if ADV_TAGS=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Custom Tags?[If you remove all, there will be no tags!]" 8 58 "${TAGS}" --title "Advanced Tags" 3>&1 1>&2 2>&3); then - if [ -n "${ADV_TAGS}" ]; then - ADV_TAGS=$(echo "$ADV_TAGS" | tr -d '[:space:]') - TAGS="${ADV_TAGS}" - else - TAGS=";" - fi - echo -e "${NETWORK}${BOLD}${DGN}Tags: ${BGN}$TAGS${CL}" - else - exit_script - fi - - SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "SSH Authorized key for root (leave empty for none)" 8 58 --title "SSH Key" 3>&1 1>&2 2>&3)" - - if [[ -z "${SSH_AUTHORIZED_KEY}" ]]; then - SSH_AUTHORIZED_KEY="" - fi - - if [[ "$PW" == -password* || -n "$SSH_AUTHORIZED_KEY" ]]; then - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" - else - SSH="no" - fi - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - else - SSH="no" - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - fi - - if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "FUSE Support" --yesno "Enable FUSE support?\nRequired for tools like rclone, mergerfs, AppImage, etc." 10 58); then - ENABLE_FUSE="yes" - else - ENABLE_FUSE="no" - fi - echo -e "${FUSE}${BOLD}${DGN}Enable FUSE Support: ${BGN}$ENABLE_FUSE${CL}" - - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERBOSE="yes" - else - VERBOSE="no" - fi - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERBOSE${CL}" - - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - write_config - else - clear - header_info - echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" - advanced_settings - fi } diagnostics_check() { - if ! [ -d "/usr/local/community-scripts" ]; then - mkdir -p /usr/local/community-scripts - fi + if ! [ -d "/usr/local/community-scripts" ]; then + mkdir -p /usr/local/community-scripts + fi - if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then - cat </usr/local/community-scripts/diagnostics + if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then + cat </usr/local/community-scripts/diagnostics DIAGNOSTICS=yes #This file is used to store the diagnostics settings for the Community-Scripts API. @@ -951,9 +950,9 @@ DIAGNOSTICS=yes #"status" #If you have any concerns, please review the source code at /misc/build.func EOF - DIAGNOSTICS="yes" - else - cat </usr/local/community-scripts/diagnostics + DIAGNOSTICS="yes" + else + cat </usr/local/community-scripts/diagnostics DIAGNOSTICS=no #This file is used to store the diagnostics settings for the Community-Scripts API. @@ -978,248 +977,248 @@ DIAGNOSTICS=no #"status" #If you have any concerns, please review the source code at /misc/build.func EOF - DIAGNOSTICS="no" - fi - else - DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' /usr/local/community-scripts/diagnostics) + DIAGNOSTICS="no" + fi + else + DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' /usr/local/community-scripts/diagnostics) - fi + fi } install_script() { - pve_check - shell_check - root_check - arch_check - ssh_check - maxkeys_check - diagnostics_check + pve_check + shell_check + root_check + arch_check + ssh_check + maxkeys_check + diagnostics_check - if systemctl is-active -q ping-instances.service; then - systemctl -q stop ping-instances.service - fi - NEXTID=$(pvesh get /cluster/nextid) - timezone=$(cat /etc/timezone) - header_info - while true; do - - TMP_CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --title "SETTINGS" \ - --menu "Choose an option:" 20 60 7 \ - "1" "Default Settings" \ - "2" "Default Settings (with verbose)" \ - "3" "Advanced Settings" \ - "4" "Use Config File" \ - "5" "Manage Default Storage" \ - "6" "Diagnostic Settings" \ - "7" "Exit" \ - --default-item "1" 3>&1 1>&2 2>&3) || true - - if [ -z "$TMP_CHOICE" ]; then - echo -e "\n${CROSS}${RD}Menu canceled. Exiting script.${CL}\n" - exit 0 + if systemctl is-active -q ping-instances.service; then + systemctl -q stop ping-instances.service fi + NEXTID=$(pvesh get /cluster/nextid) + timezone=$(cat /etc/timezone) + header_info + while true; do - CHOICE="$TMP_CHOICE" + TMP_CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --title "SETTINGS" \ + --menu "Choose an option:" 20 60 7 \ + "1" "Default Settings" \ + "2" "Default Settings (with verbose)" \ + "3" "Advanced Settings" \ + "4" "Use Config File" \ + "5" "Manage Default Storage" \ + "6" "Diagnostic Settings" \ + "7" "Exit" \ + --default-item "1" 3>&1 1>&2 2>&3) || true - case $CHOICE in - 1) - header_info - echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME${CL}" - VERBOSE="no" - METHOD="default" - base_settings "$VERBOSE" - echo_default - break - ;; - 2) - header_info - echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME (${VERBOSE_CROPPED}Verbose)${CL}" - VERBOSE="yes" - METHOD="default" - base_settings "$VERBOSE" - echo_default - break - ;; - 3) - header_info - echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" - METHOD="advanced" - base_settings - advanced_settings - break - ;; - 4) - header_info - echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" - METHOD="advanced" - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/config-file.func) - config_file - break - ;; - - 5) - manage_default_storage - ;; - 6) - if [[ $DIAGNOSTICS == "yes" ]]; then - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ - --yes-button "No" --no-button "Back"; then - DIAGNOSTICS="no" - sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 + if [ -z "$TMP_CHOICE" ]; then + echo -e "\n${CROSS}${RD}Menu canceled. Exiting script.${CL}\n" + exit 0 fi - else - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ - --yes-button "Yes" --no-button "Back"; then - DIAGNOSTICS="yes" - sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 - fi - fi - ;; - 7) - echo -e "\n${CROSS}${RD}Script terminated. Have a great day!${CL}\n" - exit 0 - ;; - *) - echo -e "${CROSS}${RD}Invalid option, please try again.${CL}" - ;; - esac - done + + CHOICE="$TMP_CHOICE" + + case $CHOICE in + 1) + header_info + echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME${CL}" + VERBOSE="no" + METHOD="default" + base_settings "$VERBOSE" + echo_default + break + ;; + 2) + header_info + echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME (${VERBOSE_CROPPED}Verbose)${CL}" + VERBOSE="yes" + METHOD="default" + base_settings "$VERBOSE" + echo_default + break + ;; + 3) + header_info + echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" + METHOD="advanced" + base_settings + advanced_settings + break + ;; + 4) + header_info + echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" + METHOD="advanced" + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/config-file.func) + config_file + break + ;; + + 5) + manage_default_storage + ;; + 6) + if [[ $DIAGNOSTICS == "yes" ]]; then + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ + --yes-button "No" --no-button "Back"; then + DIAGNOSTICS="no" + sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 + fi + else + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ + --yes-button "Yes" --no-button "Back"; then + DIAGNOSTICS="yes" + sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 + fi + fi + ;; + 7) + echo -e "\n${CROSS}${RD}Script terminated. Have a great day!${CL}\n" + exit 0 + ;; + *) + echo -e "${CROSS}${RD}Invalid option, please try again.${CL}" + ;; + esac + done } check_container_resources() { - # Check actual RAM & Cores - current_ram=$(free -m | awk 'NR==2{print $2}') - current_cpu=$(nproc) + # Check actual RAM & Cores + current_ram=$(free -m | awk 'NR==2{print $2}') + current_cpu=$(nproc) - # Check whether the current RAM is less than the required RAM or the CPU cores are less than required - if [[ "$current_ram" -lt "$var_ram" ]] || [[ "$current_cpu" -lt "$var_cpu" ]]; then - echo -e "\n${INFO}${HOLD} ${GN}Required: ${var_cpu} CPU, ${var_ram}MB RAM ${CL}| ${RD}Current: ${current_cpu} CPU, ${current_ram}MB RAM${CL}" - echo -e "${YWB}Please ensure that the ${APP} LXC is configured with at least ${var_cpu} vCPU and ${var_ram} MB RAM for the build process.${CL}\n" - echo -ne "${INFO}${HOLD} May cause data loss! ${INFO} Continue update with under-provisioned LXC? " - read -r prompt - # Check if the input is 'yes', otherwise exit with status 1 - if [[ ! ${prompt,,} =~ ^(yes)$ ]]; then - echo -e "${CROSS}${HOLD} ${YWB}Exiting based on user input.${CL}" - exit 1 + # Check whether the current RAM is less than the required RAM or the CPU cores are less than required + if [[ "$current_ram" -lt "$var_ram" ]] || [[ "$current_cpu" -lt "$var_cpu" ]]; then + echo -e "\n${INFO}${HOLD} ${GN}Required: ${var_cpu} CPU, ${var_ram}MB RAM ${CL}| ${RD}Current: ${current_cpu} CPU, ${current_ram}MB RAM${CL}" + echo -e "${YWB}Please ensure that the ${APP} LXC is configured with at least ${var_cpu} vCPU and ${var_ram} MB RAM for the build process.${CL}\n" + echo -ne "${INFO}${HOLD} May cause data loss! ${INFO} Continue update with under-provisioned LXC? " + read -r prompt + # Check if the input is 'yes', otherwise exit with status 1 + if [[ ! ${prompt,,} =~ ^(yes)$ ]]; then + echo -e "${CROSS}${HOLD} ${YWB}Exiting based on user input.${CL}" + exit 1 + fi + else + echo -e "" fi - else - echo -e "" - fi } check_container_storage() { - # Check if the /boot partition is more than 80% full - total_size=$(df /boot --output=size | tail -n 1) - local used_size=$(df /boot --output=used | tail -n 1) - usage=$((100 * used_size / total_size)) - if ((usage > 80)); then - # Prompt the user for confirmation to continue - echo -e "${INFO}${HOLD} ${YWB}Warning: Storage is dangerously low (${usage}%).${CL}" - echo -ne "Continue anyway? " - read -r prompt - # Check if the input is 'y' or 'yes', otherwise exit with status 1 - if [[ ! ${prompt,,} =~ ^(y|yes)$ ]]; then - echo -e "${CROSS}${HOLD}${YWB}Exiting based on user input.${CL}" - exit 1 + # Check if the /boot partition is more than 80% full + total_size=$(df /boot --output=size | tail -n 1) + local used_size=$(df /boot --output=used | tail -n 1) + usage=$((100 * used_size / total_size)) + if ((usage > 80)); then + # Prompt the user for confirmation to continue + echo -e "${INFO}${HOLD} ${YWB}Warning: Storage is dangerously low (${usage}%).${CL}" + echo -ne "Continue anyway? " + read -r prompt + # Check if the input is 'y' or 'yes', otherwise exit with status 1 + if [[ ! ${prompt,,} =~ ^(y|yes)$ ]]; then + echo -e "${CROSS}${HOLD}${YWB}Exiting based on user input.${CL}" + exit 1 + fi fi - fi } start() { - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) - if command -v pveversion >/dev/null 2>&1; then - install_script - elif [ ! -z ${PHS_SILENT+x} ] && [[ "${PHS_SILENT}" == "1" ]]; then - VERBOSE="no" - set_std_mode - update_script - else - CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC Update/Setting" --menu \ - "Support/Update functions for ${APP} LXC. Choose an option:" \ - 12 60 3 \ - "1" "YES (Silent Mode)" \ - "2" "YES (Verbose Mode)" \ - "3" "NO (Cancel Update)" --nocancel --default-item "1" 3>&1 1>&2 2>&3) + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) + if command -v pveversion >/dev/null 2>&1; then + install_script + elif [ ! -z ${PHS_SILENT+x} ] && [[ "${PHS_SILENT}" == "1" ]]; then + VERBOSE="no" + set_std_mode + update_script + else + CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC Update/Setting" --menu \ + "Support/Update functions for ${APP} LXC. Choose an option:" \ + 12 60 3 \ + "1" "YES (Silent Mode)" \ + "2" "YES (Verbose Mode)" \ + "3" "NO (Cancel Update)" --nocancel --default-item "1" 3>&1 1>&2 2>&3) - case "$CHOICE" in - 1) - VERBOSE="no" - set_std_mode - ;; - 2) - VERBOSE="yes" - set_std_mode - ;; - 3) - clear - exit_script - exit - ;; - esac - update_script - fi + case "$CHOICE" in + 1) + VERBOSE="no" + set_std_mode + ;; + 2) + VERBOSE="yes" + set_std_mode + ;; + 3) + clear + exit_script + exit + ;; + esac + update_script + fi } # This function collects user settings and integrates all the collected information. build_container() { - # if [ "$VERBOSE" == "yes" ]; then set -x; fi + # if [ "$VERBOSE" == "yes" ]; then set -x; fi - NET_STRING="-net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU" - case "$IPV6_METHOD" in - auto) NET_STRING="$NET_STRING,ip6=auto" ;; - dhcp) NET_STRING="$NET_STRING,ip6=dhcp" ;; - static) - NET_STRING="$NET_STRING,ip6=$IPV6_ADDR" - [ -n "$IPV6_GATE" ] && NET_STRING="$NET_STRING,gw6=$IPV6_GATE" - ;; - none) ;; - esac + NET_STRING="-net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU" + case "$IPV6_METHOD" in + auto) NET_STRING="$NET_STRING,ip6=auto" ;; + dhcp) NET_STRING="$NET_STRING,ip6=dhcp" ;; + static) + NET_STRING="$NET_STRING,ip6=$IPV6_ADDR" + [ -n "$IPV6_GATE" ] && NET_STRING="$NET_STRING,gw6=$IPV6_GATE" + ;; + none) ;; + esac - if [ "$CT_TYPE" == "1" ]; then - FEATURES="keyctl=1,nesting=1" - else - FEATURES="nesting=1" - fi + if [ "$CT_TYPE" == "1" ]; then + FEATURES="keyctl=1,nesting=1" + else + FEATURES="nesting=1" + fi - if [ "$ENABLE_FUSE" == "yes" ]; then - FEATURES="$FEATURES,fuse=1" - fi + if [ "$ENABLE_FUSE" == "yes" ]; then + FEATURES="$FEATURES,fuse=1" + fi - #if [[ $DIAGNOSTICS == "yes" ]]; then - # post_to_api - #fi + #if [[ $DIAGNOSTICS == "yes" ]]; then + # post_to_api + #fi - TEMP_DIR=$(mktemp -d) - pushd "$TEMP_DIR" >/dev/null - if [ "$var_os" == "alpine" ]; then - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)" - else - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)" - fi - export DIAGNOSTICS="$DIAGNOSTICS" - export RANDOM_UUID="$RANDOM_UUID" - export CACHER="$APT_CACHER" - export CACHER_IP="$APT_CACHER_IP" - export tz="$timezone" - #export DISABLEIPV6="$DISABLEIP6" - export APPLICATION="$APP" - export app="$NSAPP" - export PASSWORD="$PW" - export VERBOSE="$VERBOSE" - export SSH_ROOT="${SSH}" - export SSH_AUTHORIZED_KEY - export CTID="$CT_ID" - export CTTYPE="$CT_TYPE" - export ENABLE_FUSE="$ENABLE_FUSE" - export ENABLE_TUN="$ENABLE_TUN" - export PCT_OSTYPE="$var_os" - export PCT_OSVERSION="$var_version" - export PCT_DISK_SIZE="$DISK_SIZE" - export PCT_OPTIONS=" + TEMP_DIR=$(mktemp -d) + pushd "$TEMP_DIR" >/dev/null + if [ "$var_os" == "alpine" ]; then + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)" + else + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)" + fi + export DIAGNOSTICS="$DIAGNOSTICS" + export RANDOM_UUID="$RANDOM_UUID" + export CACHER="$APT_CACHER" + export CACHER_IP="$APT_CACHER_IP" + export tz="$timezone" + #export DISABLEIPV6="$DISABLEIP6" + export APPLICATION="$APP" + export app="$NSAPP" + export PASSWORD="$PW" + export VERBOSE="$VERBOSE" + export SSH_ROOT="${SSH}" + export SSH_AUTHORIZED_KEY + export CTID="$CT_ID" + export CTTYPE="$CT_TYPE" + export ENABLE_FUSE="$ENABLE_FUSE" + export ENABLE_TUN="$ENABLE_TUN" + export PCT_OSTYPE="$var_os" + export PCT_OSVERSION="$var_version" + export PCT_DISK_SIZE="$DISK_SIZE" + export PCT_OPTIONS=" -features $FEATURES -hostname $HN -tags $TAGS @@ -1232,16 +1231,16 @@ build_container() { -unprivileged $CT_TYPE $PW " - bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)" - if [ $? -ne 0 ]; then - exit 200 - fi + bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)" + if [ $? -ne 0 ]; then + exit 200 + fi - LXC_CONFIG="/etc/pve/lxc/${CTID}.conf" + LXC_CONFIG="/etc/pve/lxc/${CTID}.conf" - # USB passthrough for privileged LXC (CT_TYPE=0) - if [ "$CT_TYPE" == "0" ]; then - cat <>"$LXC_CONFIG" + # USB passthrough for privileged LXC (CT_TYPE=0) + if [ "$CT_TYPE" == "0" ]; then + cat <>"$LXC_CONFIG" # USB passthrough lxc.cgroup2.devices.allow: a lxc.cap.drop: @@ -1253,185 +1252,191 @@ lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create= lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF - fi - - # VAAPI passthrough for privileged containers or known apps - VAAPI_APPS=( - "immich" - "Channels" - "Emby" - "ErsatzTV" - "Frigate" - "Jellyfin" - "Plex" - "Scrypted" - "Tdarr" - "Unmanic" - "Ollama" - "FileFlows" - "Open WebUI" - ) - - is_vaapi_app=false - for vaapi_app in "${VAAPI_APPS[@]}"; do - if [[ "$APP" == "$vaapi_app" ]]; then - is_vaapi_app=true - break - fi - done - - if ([ "$CT_TYPE" == "0" ] || [ "$is_vaapi_app" == "true" ]) && - ([[ -e /dev/dri/renderD128 ]] || [[ -e /dev/dri/card0 ]] || [[ -e /dev/fb0 ]]); then - - echo "" - msg_custom "⚙️ " "\e[96m" "Configuring VAAPI passthrough for LXC container" - if [ "$CT_TYPE" != "0" ]; then - msg_custom "⚠️ " "\e[33m" "Container is unprivileged – VAAPI passthrough may not work without additional host configuration (e.g., idmap)." - fi - msg_custom "ℹ️ " "\e[96m" "VAAPI enables GPU hardware acceleration (e.g., for video transcoding in Jellyfin or Plex)." - echo "" - read -rp "➤ Automatically mount all available VAAPI devices? [Y/n]: " VAAPI_ALL - - if [[ "$VAAPI_ALL" =~ ^[Yy]$|^$ ]]; then - if [ "$CT_TYPE" == "0" ]; then - # PRV Container → alles zulässig - [[ -e /dev/dri/renderD128 ]] && { - echo "lxc.cgroup2.devices.allow: c 226:128 rwm" >>"$LXC_CONFIG" - echo "lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file" >>"$LXC_CONFIG" - } - [[ -e /dev/dri/card0 ]] && { - echo "lxc.cgroup2.devices.allow: c 226:0 rwm" >>"$LXC_CONFIG" - echo "lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file" >>"$LXC_CONFIG" - } - [[ -e /dev/fb0 ]] && { - echo "lxc.cgroup2.devices.allow: c 29:0 rwm" >>"$LXC_CONFIG" - echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >>"$LXC_CONFIG" - } - [[ -d /dev/dri ]] && { - echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG" - } - else - # UNPRV Container → nur devX für UI - [[ -e /dev/dri/card0 ]] && echo "dev0: /dev/dri/card0,gid=44" >>"$LXC_CONFIG" - [[ -e /dev/dri/card1 ]] && echo "dev0: /dev/dri/card1,gid=44" >>"$LXC_CONFIG" - [[ -e /dev/dri/renderD128 ]] && echo "dev1: /dev/dri/renderD128,gid=104" >>"$LXC_CONFIG" - fi fi - fi - if [ "$CT_TYPE" == "1" ] && [ "$is_vaapi_app" == "true" ]; then - if [[ -e /dev/dri/card0 ]]; then - echo "dev0: /dev/dri/card0,gid=44" >>"$LXC_CONFIG" - elif [[ -e /dev/dri/card1 ]]; then - echo "dev0: /dev/dri/card1,gid=44" >>"$LXC_CONFIG" - fi - if [[ -e /dev/dri/renderD128 ]]; then - echo "dev1: /dev/dri/renderD128,gid=104" >>"$LXC_CONFIG" - fi - fi + # VAAPI passthrough for privileged containers or known apps + VAAPI_APPS=( + "immich" + "Channels" + "Emby" + "ErsatzTV" + "Frigate" + "Jellyfin" + "Plex" + "Scrypted" + "Tdarr" + "Unmanic" + "Ollama" + "FileFlows" + "Open WebUI" + ) - # TUN device passthrough - if [ "$ENABLE_TUN" == "yes" ]; then - cat <>"$LXC_CONFIG" + is_vaapi_app=false + for vaapi_app in "${VAAPI_APPS[@]}"; do + if [[ "$APP" == "$vaapi_app" ]]; then + is_vaapi_app=true + break + fi + done + + if ([ "$CT_TYPE" == "0" ] || [ "$is_vaapi_app" == "true" ]) && + ([[ -e /dev/dri/renderD128 ]] || [[ -e /dev/dri/card0 ]] || [[ -e /dev/fb0 ]]); then + + echo "" + msg_custom "⚙️ " "\e[96m" "Configuring VAAPI passthrough for LXC container" + if [ "$CT_TYPE" != "0" ]; then + msg_custom "⚠️ " "\e[33m" "Container is unprivileged – VAAPI passthrough may not work without additional host configuration (e.g., idmap)." + fi + msg_custom "ℹ️ " "\e[96m" "VAAPI enables GPU hardware acceleration (e.g., for video transcoding in Jellyfin or Plex)." + echo "" + read -rp "➤ Automatically mount all available VAAPI devices? [Y/n]: " VAAPI_ALL + + if [[ "$VAAPI_ALL" =~ ^[Yy]$|^$ ]]; then + if [ "$CT_TYPE" == "0" ]; then + # PRV Container → alles zulässig + [[ -e /dev/dri/renderD128 ]] && { + echo "lxc.cgroup2.devices.allow: c 226:128 rwm" >>"$LXC_CONFIG" + echo "lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file" >>"$LXC_CONFIG" + } + [[ -e /dev/dri/card0 ]] && { + echo "lxc.cgroup2.devices.allow: c 226:0 rwm" >>"$LXC_CONFIG" + echo "lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file" >>"$LXC_CONFIG" + } + [[ -e /dev/fb0 ]] && { + echo "lxc.cgroup2.devices.allow: c 29:0 rwm" >>"$LXC_CONFIG" + echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >>"$LXC_CONFIG" + } + [[ -d /dev/dri ]] && { + echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG" + } + else + # UNPRV Container → nur devX für UI + [[ -e /dev/dri/card0 ]] && echo "dev0: /dev/dri/card0,gid=44" >>"$LXC_CONFIG" + [[ -e /dev/dri/card1 ]] && echo "dev0: /dev/dri/card1,gid=44" >>"$LXC_CONFIG" + [[ -e /dev/dri/renderD128 ]] && echo "dev1: /dev/dri/renderD128,gid=104" >>"$LXC_CONFIG" + fi + fi + + fi + if [ "$CT_TYPE" == "1" ] && [ "$is_vaapi_app" == "true" ]; then + if [[ -e /dev/dri/card0 ]]; then + echo "dev0: /dev/dri/card0,gid=44" >>"$LXC_CONFIG" + elif [[ -e /dev/dri/card1 ]]; then + echo "dev0: /dev/dri/card1,gid=44" >>"$LXC_CONFIG" + fi + if [[ -e /dev/dri/renderD128 ]]; then + echo "dev1: /dev/dri/renderD128,gid=104" >>"$LXC_CONFIG" + fi + fi + + # TUN device passthrough + if [ "$ENABLE_TUN" == "yes" ]; then + cat <>"$LXC_CONFIG" lxc.cgroup2.devices.allow: c 10:200 rwm lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file EOF - fi + fi - # This starts the container and executes -install.sh - msg_info "Starting LXC Container" - pct start "$CTID" + # This starts the container and executes -install.sh + msg_info "Starting LXC Container" + pct start "$CTID" - # wait for status 'running' + # wait for status 'running' for i in {1..10}; do - if pct status "$CTID" | grep -q "status: running"; then - msg_ok "Startted LXC Container" - break - fi - sleep 1 - if [ "$i" -eq 10 ]; then - msg_error "LXC Container did not reach running state" - exit 1 - fi - done - - msg_info "Waiting for network in LXC container" - for i in {1..10}; do - if pct exec "$CTID" -- ping -c1 -W1 deb.debian.org >/dev/null 2>&1; then - msg_ok "Network in LXC is reachable" - break - fi - if [ "$i" -lt 10 ]; then - msg_warn "No network yet in LXC (try $i/10) – waiting..." - sleep 3 - else - msg_error "No network in LXC after waiting." - read -r -p "Set fallback DNS (1.1.1.1/8.8.8.8)? [y/N]: " choice - case "$choice" in - [yY]*) - pct set "$CTID" --nameserver 1.1.1.1 - pct set "$CTID" --nameserver 8.8.8.8 - if pct exec "$CTID" -- ping -c1 -W1 deb.debian.org >/dev/null 2>&1; then - msg_ok "Network reachable after DNS fallback" - else - msg_error "Still no network/DNS in LXC! Aborting customization." + if pct status "$CTID" | grep -q "status: running"; then + msg_ok "Startted LXC Container" + break + fi + sleep 1 + if [ "$i" -eq 10 ]; then + msg_error "LXC Container did not reach running state" exit 1 - fi - ;; - *) - msg_error "Aborted by user – no DNS fallback set." - exit 1 - ;; - esac - fi - done + fi + done - msg_info "Customizing LXC Container" - if [ "$var_os" == "alpine" ]; then - sleep 3 - pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories + if [ "$var_os" == "alpine" ]; then + PING_TARGET="alpinelinux.org" + else + PING_TARGET="deb.debian.org" + fi + + msg_info "Waiting for network in LXC container" + for i in {1..10}; do + if pct exec "$CTID" -- ping -c1 -W1 "$PING_TARGET" >/dev/null 2>&1; then + msg_ok "Network in LXC is reachable" + break + fi + if [ "$i" -lt 10 ]; then + msg_warn "No network yet in LXC (try $i/10) – waiting..." + sleep 3 + else + msg_error "No network in LXC after waiting." + read -r -p "Set fallback DNS (1.1.1.1/8.8.8.8)? [y/N]: " choice + case "$choice" in + [yY]*) + pct set "$CTID" --nameserver 1.1.1.1 + pct set "$CTID" --nameserver 8.8.8.8 + if pct exec "$CTID" -- ping -c1 -W1 "$PING_TARGET" >/dev/null 2>&1; then + msg_ok "Network reachable after DNS fallback" + else + msg_error "Still no network/DNS in LXC! Aborting customization." + exit 1 + fi + ;; + *) + msg_error "Aborted by user – no DNS fallback set." + exit 1 + ;; + esac + fi + done + + msg_info "Customizing LXC Container" + if [ "$var_os" == "alpine" ]; then + sleep 3 + pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories http://dl-cdn.alpinelinux.org/alpine/latest-stable/main http://dl-cdn.alpinelinux.org/alpine/latest-stable/community EOF' - pct exec "$CTID" -- ash -c "apk add bash newt curl openssh nano mc ncurses >/dev/null" - else - sleep 3 + pct exec "$CTID" -- ash -c "apk add bash newt curl openssh nano mc ncurses >/dev/null" + else + sleep 3 - pct exec "$CTID" -- bash -c "sed -i '/$LANG/ s/^# //' /etc/locale.gen" - pct exec "$CTID" -- bash -c "locale_line=\$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print \$1}' | head -n 1) && \ + pct exec "$CTID" -- bash -c "sed -i '/$LANG/ s/^# //' /etc/locale.gen" + pct exec "$CTID" -- bash -c "locale_line=\$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print \$1}' | head -n 1) && \ echo LANG=\$locale_line >/etc/default/locale && \ locale-gen >/dev/null && \ export LANG=\$locale_line" - if [[ -z "${tz:-}" ]]; then - tz=$(timedatectl show --property=Timezone --value 2>/dev/null || echo "Etc/UTC") + if [[ -z "${tz:-}" ]]; then + tz=$(timedatectl show --property=Timezone --value 2>/dev/null || echo "Etc/UTC") + fi + + if pct exec "$CTID" -- test -e "/usr/share/zoneinfo/$tz"; then + pct exec "$CTID" -- bash -c "tz='$tz'; echo \"\$tz\" >/etc/timezone && ln -sf \"/usr/share/zoneinfo/\$tz\" /etc/localtime" + else + msg_warn "Skipping timezone setup – zone '$tz' not found in container" + fi + + pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" || { + msg_error "apt-get base packages installation failed" + exit 1 + } fi + msg_ok "Customized LXC Container" - if pct exec "$CTID" -- test -e "/usr/share/zoneinfo/$tz"; then - pct exec "$CTID" -- bash -c "tz='$tz'; echo \"\$tz\" >/etc/timezone && ln -sf \"/usr/share/zoneinfo/\$tz\" /etc/localtime" - else - msg_warn "Skipping timezone setup – zone '$tz' not found in container" + if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/"$var_install".sh)"; then + return fi - - pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" || { - msg_error "apt-get base packages installation failed" - exit 1 - } - fi - msg_ok "Customized LXC Container" - - if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/"$var_install".sh)"; then - return - fi } # This function sets the description of the container. description() { - IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) + IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - # Generate LXC Description - DESCRIPTION=$( - cat < Logo @@ -1459,41 +1464,41 @@ description() { EOF - ) + ) - # Set Description in LXC - pct set "$CTID" -description "$DESCRIPTION" + # Set Description in LXC + pct set "$CTID" -description "$DESCRIPTION" - if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service - fi + if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service + fi - post_update_to_api "done" "none" + post_update_to_api "done" "none" } api_exit_script() { - exit_code=$? - if [ $exit_code -ne 0 ]; then - case $exit_code in - 100) post_update_to_api "failed" "100: Unexpected error in create_lxc.sh" ;; - 101) post_update_to_api "failed" "101: No network connection detected in create_lxc.sh" ;; - 200) post_update_to_api "failed" "200: LXC creation failed in create_lxc.sh" ;; - 201) post_update_to_api "failed" "201: Invalid Storage class in create_lxc.sh" ;; - 202) post_update_to_api "failed" "202: User aborted menu in create_lxc.sh" ;; - 203) post_update_to_api "failed" "203: CTID not set in create_lxc.sh" ;; - 204) post_update_to_api "failed" "204: PCT_OSTYPE not set in create_lxc.sh" ;; - 205) post_update_to_api "failed" "205: CTID cannot be less than 100 in create_lxc.sh" ;; - 206) post_update_to_api "failed" "206: CTID already in use in create_lxc.sh" ;; - 207) post_update_to_api "failed" "207: Template not found in create_lxc.sh" ;; - 208) post_update_to_api "failed" "208: Error downloading template in create_lxc.sh" ;; - 209) post_update_to_api "failed" "209: Container creation failed, but template is intact in create_lxc.sh" ;; - *) post_update_to_api "failed" "Unknown error, exit code: $exit_code in create_lxc.sh" ;; - esac - fi + exit_code=$? + if [ $exit_code -ne 0 ]; then + case $exit_code in + 100) post_update_to_api "failed" "100: Unexpected error in create_lxc.sh" ;; + 101) post_update_to_api "failed" "101: No network connection detected in create_lxc.sh" ;; + 200) post_update_to_api "failed" "200: LXC creation failed in create_lxc.sh" ;; + 201) post_update_to_api "failed" "201: Invalid Storage class in create_lxc.sh" ;; + 202) post_update_to_api "failed" "202: User aborted menu in create_lxc.sh" ;; + 203) post_update_to_api "failed" "203: CTID not set in create_lxc.sh" ;; + 204) post_update_to_api "failed" "204: PCT_OSTYPE not set in create_lxc.sh" ;; + 205) post_update_to_api "failed" "205: CTID cannot be less than 100 in create_lxc.sh" ;; + 206) post_update_to_api "failed" "206: CTID already in use in create_lxc.sh" ;; + 207) post_update_to_api "failed" "207: Template not found in create_lxc.sh" ;; + 208) post_update_to_api "failed" "208: Error downloading template in create_lxc.sh" ;; + 209) post_update_to_api "failed" "209: Container creation failed, but template is intact in create_lxc.sh" ;; + *) post_update_to_api "failed" "Unknown error, exit code: $exit_code in create_lxc.sh" ;; + esac + fi } if command -v pveversion >/dev/null 2>&1; then - trap 'api_exit_script' EXIT + trap 'api_exit_script' EXIT fi trap 'post_update_to_api "failed" "$BASH_COMMAND"' ERR trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT From 7b814adc983506a658c494807830ee43d2615557 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 09:42:39 +0200 Subject: [PATCH 439/463] Update linkstack.sh --- ct/linkstack.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ct/linkstack.sh b/ct/linkstack.sh index 731033bf..fb421c8e 100644 --- a/ct/linkstack.sh +++ b/ct/linkstack.sh @@ -24,7 +24,7 @@ function update_script() { check_container_storage check_container_resources - if [[ ! -f /.linkstack ]]; then + if [[ ! -f ~/.linkstack ]]; then msg_error "No ${APP} Installation Found!" exit fi @@ -62,7 +62,6 @@ function update_script() { exit } - start build_container description From ba97ccea75143704d6902c36ecc4e569feae1100 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 09:44:40 +0200 Subject: [PATCH 440/463] spell issue --- ct/linkstack.sh | 2 +- install/linkstack-install.sh | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/linkstack.sh b/ct/linkstack.sh index fb421c8e..a1a63356 100644 --- a/ct/linkstack.sh +++ b/ct/linkstack.sh @@ -49,7 +49,7 @@ function update_script() { msg_ok "Updated $APP to v${RELEASE}" msg_info "Starting $APP" - systemctl start linkstack + systemctl start apache2 msg_ok "Started $APP" msg_info "Cleaning Up" diff --git a/install/linkstack-install.sh b/install/linkstack-install.sh index 7e87a8a5..95105bbf 100644 --- a/install/linkstack-install.sh +++ b/install/linkstack-install.sh @@ -13,7 +13,6 @@ setting_up_container network_check update_os - PHP_VERSION="8.3" PHP_MODULE="sqlite3" PHP_APACHE="YES" setup_php fetch_and_deploy_gh_release "linkstack" "linkstackorg/linkstack" "prebuild" "latest" "/var/www/html/linkstack" "linkstack.zip" @@ -22,7 +21,7 @@ $STD a2enmod rewrite chown -R www-data:www-data /var/www/html/linkstack chmod -R 755 /var/www/html/linkstack -cat < /etc/apache2/sites-available/linkstack.conf +cat </etc/apache2/sites-available/linkstack.conf ServerAdmin webmaster@localhost DocumentRoot /var/www/html/linkstack From 8c4a7a80ec4271457828231d8f0f84a629a3998c Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 10:01:03 +0200 Subject: [PATCH 441/463] Update tools.func --- misc/tools.func | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 92a5bac5..9c067e64 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -472,10 +472,12 @@ function setup_php() { $STD systemctl disable php${CURRENT_PHP}-fpm || true fi - $STD apt-get install -y $MODULE_LIST - msg_ok "Setup PHP $PHP_VERSION" - if [[ "$PHP_APACHE" == "YES" ]]; then + if [[ -f /etc/apache2/mods-enabled/php${PHP_VERSION}.load ]]; then + $STD a2enmod php${PHP_VERSION} + else + $STD a2enmod php${PHP_VERSION} + fi $STD systemctl restart apache2 || true fi @@ -499,6 +501,17 @@ function setup_php() { $STD msg_ok "Patched $ini" fi done + + # patch Apache configuration if needed + for mod in $(ls /etc/apache2/mods-enabled/ | grep -E '^php[0-9]\.[0-9]\.conf$' | sed 's/\.conf//'); do + if [[ "$mod" != "php${PHP_VERSION}" ]]; then + $STD a2dismod "$mod" || true + fi + done + $STD a2enmod "php${PHP_VERSION}" + if [[ "$PHP_APACHE" == "YES" ]]; then + $STD systemctl restart apache2 || true + fi } # ------------------------------------------------------------------------------ From 7cf8f67f6e9c0d4cb3ee489fe2e319d319508f86 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 10:11:08 +0200 Subject: [PATCH 442/463] Update linkstack.sh --- ct/linkstack.sh | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/ct/linkstack.sh b/ct/linkstack.sh index a1a63356..e745545f 100644 --- a/ct/linkstack.sh +++ b/ct/linkstack.sh @@ -28,37 +28,8 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi - - RELEASE=$(curl -fsSL https://api.github.com/repos/linkstackorg/linkstack/releases/latest | jq -r '.tag_name | ltrimstr("v")') - if [[ "${RELEASE}" != "$(cat ~/.linkstack 2>/dev/null)" ]] || [[ ! -f ~/.linkstack ]]; then - msg_info "Stopping $APP" - systemctl stop apache2 - msg_ok "Stopped $APP" - - msg_info "Creating Backup" - BACKUP_FILE="/opt/linkstack_backup_$(date +%F).tar.gz" - $STD tar -czf "$BACKUP_FILE" /var/www/html/linkstack - msg_ok "Backup Created" - - PHP_VERSION="8.3" PHP_MODULE="sqlite3" PHP_APACHE="YES" setup_php - fetch_and_deploy_gh_release "linkstack" "linkstackorg/linkstack" "prebuild" "latest" "/var/www/html/linkstack" "linkstack.zip" - - msg_info "Updating $APP to v${RELEASE}" - chown -R www-data:www-data /var/www/html/linkstack - chmod -R 755 /var/www/html/linkstack - msg_ok "Updated $APP to v${RELEASE}" - - msg_info "Starting $APP" - systemctl start apache2 - msg_ok "Started $APP" - - msg_info "Cleaning Up" - rm -rf "$BACKUP_FILE" - msg_ok "Cleanup Completed" - msg_ok "Update Successful" - else - msg_ok "No update required. ${APP} is already at v${RELEASE}" - fi + PHP_VERSION="8.3" PHP_MODULE="sqlite3" PHP_APACHE="YES" setup_php + msg_error "Adguard Home should be updated via the user interface." exit } From 18a99c9aa730d3849b34177bf664366d379c9bc3 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 10:26:18 +0200 Subject: [PATCH 443/463] Update tools.func --- misc/tools.func | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 9c067e64..89d17102 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -393,7 +393,6 @@ function setup_mysql() { # PHP_POST_MAX_SIZE - (default: 128M) # PHP_MAX_EXECUTION_TIME - (default: 300) # ------------------------------------------------------------------------------ - function setup_php() { local PHP_VERSION="${PHP_VERSION:-8.4}" local PHP_MODULE="${PHP_MODULE:-}" @@ -450,7 +449,11 @@ function setup_php() { done IFS=',' read -ra MODULES <<<"$COMBINED_MODULES" for mod in "${MODULES[@]}"; do - MODULE_LIST+=" php${PHP_VERSION}-${mod}" + if apt-cache show "php${PHP_VERSION}-${mod}" >/dev/null 2>&1; then + MODULE_LIST+=" php${PHP_VERSION}-${mod}" + else + msg_warn "PHP-Module ${mod} for PHP ${PHP_VERSION} not found – skipping" + fi done if [[ "$PHP_FPM" == "YES" ]]; then @@ -463,27 +466,31 @@ function setup_php() { if [[ "$PHP_APACHE" == "YES" ]] && [[ -n "$CURRENT_PHP" ]]; then if [[ -f /etc/apache2/mods-enabled/php${CURRENT_PHP}.load ]]; then - $STD a2dismod php${CURRENT_PHP} || true + $STD a2dismod php"${CURRENT_PHP}" || true fi fi if [[ "$PHP_FPM" == "YES" ]] && [[ -n "$CURRENT_PHP" ]]; then - $STD systemctl stop php${CURRENT_PHP}-fpm || true - $STD systemctl disable php${CURRENT_PHP}-fpm || true + $STD systemctl stop php"${CURRENT_PHP}"-fpm || true + $STD systemctl disable php"${CURRENT_PHP}"-fpm || true fi if [[ "$PHP_APACHE" == "YES" ]]; then if [[ -f /etc/apache2/mods-enabled/php${PHP_VERSION}.load ]]; then - $STD a2enmod php${PHP_VERSION} + $STD a2enmod php"${PHP_VERSION}" else - $STD a2enmod php${PHP_VERSION} + $STD a2enmod php"${PHP_VERSION}" fi $STD systemctl restart apache2 || true fi if [[ "$PHP_FPM" == "YES" ]]; then - $STD systemctl enable php${PHP_VERSION}-fpm - $STD systemctl restart php${PHP_VERSION}-fpm + if systemctl list-unit-files | grep -q "php${PHP_VERSION}-fpm.service"; then + $STD systemctl enable php${PHP_VERSION}-fpm + $STD systemctl restart php${PHP_VERSION}-fpm + else + msg_warn "FPM requested but service php${PHP_VERSION}-fpm not found" + fi fi # Patch all relevant php.ini files @@ -503,13 +510,13 @@ function setup_php() { done # patch Apache configuration if needed - for mod in $(ls /etc/apache2/mods-enabled/ | grep -E '^php[0-9]\.[0-9]\.conf$' | sed 's/\.conf//'); do - if [[ "$mod" != "php${PHP_VERSION}" ]]; then - $STD a2dismod "$mod" || true - fi - done - $STD a2enmod "php${PHP_VERSION}" if [[ "$PHP_APACHE" == "YES" ]]; then + for mod in $(ls /etc/apache2/mods-enabled/ 2>/dev/null | grep -E '^php[0-9]\.[0-9]\.conf$' | sed 's/\.conf//'); do + if [[ "$mod" != "php${PHP_VERSION}" ]]; then + $STD a2dismod "$mod" || true + fi + done + $STD a2enmod "php${PHP_VERSION}" $STD systemctl restart apache2 || true fi } From 001e3187176dc36719a09c30e91985fdbc571190 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 10:26:31 +0200 Subject: [PATCH 444/463] Update linkstack-install.sh --- install/linkstack-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/linkstack-install.sh b/install/linkstack-install.sh index 95105bbf..81fb19bb 100644 --- a/install/linkstack-install.sh +++ b/install/linkstack-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -PHP_VERSION="8.3" PHP_MODULE="sqlite3" PHP_APACHE="YES" setup_php +PHP_VERSION="8.3" PHP_MODULE="sqlite3,mysql" PHP_APACHE="YES" setup_php fetch_and_deploy_gh_release "linkstack" "linkstackorg/linkstack" "prebuild" "latest" "/var/www/html/linkstack" "linkstack.zip" msg_info "Configuring LinkStack" From d37fcf79e70ba024bd204d9d61257ec07f22c80d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 10:30:07 +0200 Subject: [PATCH 445/463] Update build.func --- misc/build.func | 2114 +++++++++++++++++++++++------------------------ 1 file changed, 1057 insertions(+), 1057 deletions(-) diff --git a/misc/build.func b/misc/build.func index 58805155..80265458 100644 --- a/misc/build.func +++ b/misc/build.func @@ -6,210 +6,210 @@ # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE variables() { - NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. - var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. - INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. - PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase - DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call. - METHOD="default" # sets the METHOD variable to "default", used for the API call. - RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable. - CT_TYPE=${var_unprivileged:-$CT_TYPE} + NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. + var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. + INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. + PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase + DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call. + METHOD="default" # sets the METHOD variable to "default", used for the API call. + RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable. + CT_TYPE=${var_unprivileged:-$CT_TYPE} } source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) if command -v curl >/dev/null 2>&1; then - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) - load_functions - #echo "(build.func) Loaded core.func via curl" + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) + load_functions + #echo "(build.func) Loaded core.func via curl" elif command -v wget >/dev/null 2>&1; then - source <(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) - load_functions - #echo "(build.func) Loaded core.func via wget" + source <(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) + load_functions + #echo "(build.func) Loaded core.func via wget" fi # This function enables error handling in the script by setting options and defining a trap for the ERR signal. catch_errors() { - set -Eeo pipefail - # if [ -n "$BASH_VERSION" ] && command -v shopt >/dev/null 2>&1; then - # shopt -s errtrace - # fi - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + set -Eeo pipefail + # if [ -n "$BASH_VERSION" ] && command -v shopt >/dev/null 2>&1; then + # shopt -s errtrace + # fi + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - printf "\e[?25h" - local error_message="[ERROR] in line $line_number: exit code $exit_code: while executing command $command" - post_update_to_api "failed" "$command" - echo -e "\n$error_message\n" - exit "$exit_code" + local exit_code="$?" + local line_number="$1" + local command="$2" + printf "\e[?25h" + local error_message="[ERROR] in line $line_number: exit code $exit_code: while executing command $command" + post_update_to_api "failed" "$command" + echo -e "\n$error_message\n" + exit "$exit_code" - if [[ -n "$CT_ID" ]]; then - read -p "Remove this Container? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - pct stop "$CT_ID" &>/dev/null - pct destroy "$CT_ID" &>/dev/null - msg_ok "Removed this Container" - fi + if [[ -n "$CT_ID" ]]; then + read -p "Remove this Container? " prompt + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + pct stop "$CT_ID" &>/dev/null + pct destroy "$CT_ID" &>/dev/null + msg_ok "Removed this Container" fi + fi } # Check if the shell is using bash shell_check() { - if [[ "$(basename "$SHELL")" != "bash" ]]; then - clear - msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." - echo -e "\nExiting..." - sleep 2 - exit - fi + if [[ "$(basename "$SHELL")" != "bash" ]]; then + clear + msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." + echo -e "\nExiting..." + sleep 2 + exit + fi } # Run as root only root_check() { - if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then - clear - msg_error "Please run this script as root." - echo -e "\nExiting..." - sleep 2 - exit - fi + if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit + fi } # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { - local PVE_VER - PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')" + local PVE_VER + PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')" - # 8 Version Check - if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then - local MINOR="${BASH_REMATCH[1]}" - if ((MINOR < 1 || MINOR > 4)); then - msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires Proxmox Virtual Environment Version 8.1 – 8.4" - echo -e "Exiting..." - sleep 2 - exit 1 - fi - return 0 + # 8 Version Check + if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then + local MINOR="${BASH_REMATCH[1]}" + if ((MINOR < 1 || MINOR > 4)); then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires Proxmox Virtual Environment Version 8.1 – 8.4" + echo -e "Exiting..." + sleep 2 + exit 1 fi + return 0 + fi - # 9 Beta Version Check - if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then - msg_custom "Detected Proxmox Virtual Environment $PVE_VER – Beta state, use with caution!" - return 0 - fi + # 9 Beta Version Check + if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then + msg_custom "Detected Proxmox Virtual Environment $PVE_VER – Beta state, use with caution!" + return 0 + fi - # All others (unsupported versions) - msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires Proxmox Virtual Environment Version 8.1 – 8.4 or 9.x (Beta)" - echo -e "Exiting..." - sleep 2 - exit 1 + # All others (unsupported versions) + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires Proxmox Virtual Environment Version 8.1 – 8.4 or 9.x (Beta)" + echo -e "Exiting..." + sleep 2 + exit 1 } # When a node is running tens of containers, it's possible to exceed the kernel's cryptographic key storage allocations. # These are tuneable, so verify if the currently deployment is approaching the limits, advise the user on how to tune the limits, and exit the script. # https://cleveruptime.com/docs/files/proc-key-users | https://docs.kernel.org/security/keys/core.html maxkeys_check() { - # Read kernel parameters - per_user_maxkeys=$(cat /proc/sys/kernel/keys/maxkeys 2>/dev/null || echo 0) - per_user_maxbytes=$(cat /proc/sys/kernel/keys/maxbytes 2>/dev/null || echo 0) + # Read kernel parameters + per_user_maxkeys=$(cat /proc/sys/kernel/keys/maxkeys 2>/dev/null || echo 0) + per_user_maxbytes=$(cat /proc/sys/kernel/keys/maxbytes 2>/dev/null || echo 0) - # Exit if kernel parameters are unavailable - if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then - echo -e "${CROSS}${RD} Error: Unable to read kernel parameters. Ensure proper permissions.${CL}" - exit 1 - fi + # Exit if kernel parameters are unavailable + if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then + echo -e "${CROSS}${RD} Error: Unable to read kernel parameters. Ensure proper permissions.${CL}" + exit 1 + fi - # Fetch key usage for user ID 100000 (typical for containers) - used_lxc_keys=$(awk '/100000:/ {print $2}' /proc/key-users 2>/dev/null || echo 0) - used_lxc_bytes=$(awk '/100000:/ {split($5, a, "/"); print a[1]}' /proc/key-users 2>/dev/null || echo 0) + # Fetch key usage for user ID 100000 (typical for containers) + used_lxc_keys=$(awk '/100000:/ {print $2}' /proc/key-users 2>/dev/null || echo 0) + used_lxc_bytes=$(awk '/100000:/ {split($5, a, "/"); print a[1]}' /proc/key-users 2>/dev/null || echo 0) - # Calculate thresholds and suggested new limits - threshold_keys=$((per_user_maxkeys - 100)) - threshold_bytes=$((per_user_maxbytes - 1000)) - new_limit_keys=$((per_user_maxkeys * 2)) - new_limit_bytes=$((per_user_maxbytes * 2)) + # Calculate thresholds and suggested new limits + threshold_keys=$((per_user_maxkeys - 100)) + threshold_bytes=$((per_user_maxbytes - 1000)) + new_limit_keys=$((per_user_maxkeys * 2)) + new_limit_bytes=$((per_user_maxbytes * 2)) - # Check if key or byte usage is near limits - failure=0 - if [[ "$used_lxc_keys" -gt "$threshold_keys" ]]; then - echo -e "${CROSS}${RD} Warning: Key usage is near the limit (${used_lxc_keys}/${per_user_maxkeys}).${CL}" - echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxkeys=${new_limit_keys}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." - failure=1 - fi - if [[ "$used_lxc_bytes" -gt "$threshold_bytes" ]]; then - echo -e "${CROSS}${RD} Warning: Key byte usage is near the limit (${used_lxc_bytes}/${per_user_maxbytes}).${CL}" - echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxbytes=${new_limit_bytes}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." - failure=1 - fi + # Check if key or byte usage is near limits + failure=0 + if [[ "$used_lxc_keys" -gt "$threshold_keys" ]]; then + echo -e "${CROSS}${RD} Warning: Key usage is near the limit (${used_lxc_keys}/${per_user_maxkeys}).${CL}" + echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxkeys=${new_limit_keys}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." + failure=1 + fi + if [[ "$used_lxc_bytes" -gt "$threshold_bytes" ]]; then + echo -e "${CROSS}${RD} Warning: Key byte usage is near the limit (${used_lxc_bytes}/${per_user_maxbytes}).${CL}" + echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxbytes=${new_limit_bytes}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}." + failure=1 + fi - # Provide next steps if issues are detected - if [[ "$failure" -eq 1 ]]; then - echo -e "${INFO} To apply changes, run: ${BOLD}service procps force-reload${CL}" - exit 1 - fi + # Provide next steps if issues are detected + if [[ "$failure" -eq 1 ]]; then + echo -e "${INFO} To apply changes, run: ${BOLD}service procps force-reload${CL}" + exit 1 + fi - echo -e "${CM}${GN} All kernel key limits are within safe thresholds.${CL}" + echo -e "${CM}${GN} All kernel key limits are within safe thresholds.${CL}" } # This function checks the system architecture and exits if it's not "amd64". arch_check() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n" - echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" - echo -e "Exiting..." - sleep 2 - exit - fi + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n" + echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" + echo -e "Exiting..." + sleep 2 + exit + fi } # Function to get the current IP address based on the distribution get_current_ip() { - if [ -f /etc/os-release ]; then - # Check for Debian/Ubuntu (uses hostname -I) - if grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then - CURRENT_IP=$(hostname -I | awk '{print $1}') - # Check for Alpine (uses ip command) - elif grep -q 'ID=alpine' /etc/os-release; then - CURRENT_IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) - else - CURRENT_IP="Unknown" - fi + if [ -f /etc/os-release ]; then + # Check for Debian/Ubuntu (uses hostname -I) + if grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then + CURRENT_IP=$(hostname -I | awk '{print $1}') + # Check for Alpine (uses ip command) + elif grep -q 'ID=alpine' /etc/os-release; then + CURRENT_IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) + else + CURRENT_IP="Unknown" fi - echo "$CURRENT_IP" + fi + echo "$CURRENT_IP" } # Function to update the IP address in the MOTD file update_motd_ip() { - MOTD_FILE="/etc/motd" + MOTD_FILE="/etc/motd" - if [ -f "$MOTD_FILE" ]; then - # Remove existing IP Address lines to prevent duplication - sed -i '/IP Address:/d' "$MOTD_FILE" + if [ -f "$MOTD_FILE" ]; then + # Remove existing IP Address lines to prevent duplication + sed -i '/IP Address:/d' "$MOTD_FILE" - IP=$(get_current_ip) - # Add the new IP address - echo -e "${TAB}${NETWORK}${YW} IP Address: ${GN}${IP}${CL}" >>"$MOTD_FILE" - fi + IP=$(get_current_ip) + # Add the new IP address + echo -e "${TAB}${NETWORK}${YW} IP Address: ${GN}${IP}${CL}" >>"$MOTD_FILE" + fi } # This function checks if the script is running through SSH and prompts the user to confirm if they want to proceed or exit. ssh_check() { - if [ -n "${SSH_CLIENT:+x}" ]; then - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's advisable to utilize the Proxmox shell rather than SSH, as there may be potential complications with variable retrieval. Proceed using SSH?" 10 72; then - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Proceed using SSH" "You've chosen to proceed using SSH. If any issues arise, please run the script in the Proxmox shell before creating a repository issue." 10 72 - else - clear - echo "Exiting due to SSH usage. Please consider using the Proxmox shell." - exit - fi + if [ -n "${SSH_CLIENT:+x}" ]; then + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's advisable to utilize the Proxmox shell rather than SSH, as there may be potential complications with variable retrieval. Proceed using SSH?" 10 72; then + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Proceed using SSH" "You've chosen to proceed using SSH. If any issues arise, please run the script in the Proxmox shell before creating a repository issue." 10 72 + else + clear + echo "Exiting due to SSH usage. Please consider using the Proxmox shell." + exit fi + fi } # select_storage() { @@ -300,62 +300,62 @@ ssh_check() { # } base_settings() { - # Default Settings - CT_TYPE="1" - DISK_SIZE="4" - CORE_COUNT="1" - RAM_SIZE="1024" - VERBOSE="${1:-no}" - PW="" - CT_ID=$NEXTID - HN=$NSAPP - BRG="vmbr0" - NET="dhcp" - IPV6_METHOD="none" - IPV6_STATIC="" - GATE="" - APT_CACHER="" - APT_CACHER_IP="" - #DISABLEIP6="no" - MTU="" - SD="" - NS="" - MAC="" - VLAN="" - SSH="no" - SSH_AUTHORIZED_KEY="" - UDHCPC_FIX="" - TAGS="community-script;" - ENABLE_FUSE="${1:-no}" - ENABLE_TUN="${1:-no}" + # Default Settings + CT_TYPE="1" + DISK_SIZE="4" + CORE_COUNT="1" + RAM_SIZE="1024" + VERBOSE="${1:-no}" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + BRG="vmbr0" + NET="dhcp" + IPV6_METHOD="none" + IPV6_STATIC="" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + #DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + SSH_AUTHORIZED_KEY="" + UDHCPC_FIX="" + TAGS="community-script;" + ENABLE_FUSE="${1:-no}" + ENABLE_TUN="${1:-no}" - # Override default settings with variables from ct script - CT_TYPE=${var_unprivileged:-$CT_TYPE} - DISK_SIZE=${var_disk:-$DISK_SIZE} - CORE_COUNT=${var_cpu:-$CORE_COUNT} - RAM_SIZE=${var_ram:-$RAM_SIZE} - VERB=${var_verbose:-$VERBOSE} - TAGS="${TAGS}${var_tags:-}" - ENABLE_FUSE="${var_fuse:-$ENABLE_FUSE}" - ENABLE_TUN="${var_tun:-$ENABLE_TUN}" - APT_CACHER="${var_apt_cacher:-$APT_CACHER}" - APT_CACHER_IP="${var_apt_cacher_ip:-$APT_CACHER_IP}" + # Override default settings with variables from ct script + CT_TYPE=${var_unprivileged:-$CT_TYPE} + DISK_SIZE=${var_disk:-$DISK_SIZE} + CORE_COUNT=${var_cpu:-$CORE_COUNT} + RAM_SIZE=${var_ram:-$RAM_SIZE} + VERB=${var_verbose:-$VERBOSE} + TAGS="${TAGS}${var_tags:-}" + ENABLE_FUSE="${var_fuse:-$ENABLE_FUSE}" + ENABLE_TUN="${var_tun:-$ENABLE_TUN}" + APT_CACHER="${var_apt_cacher:-$APT_CACHER}" + APT_CACHER_IP="${var_apt_cacher_ip:-$APT_CACHER_IP}" - # Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts - if [ -z "$var_os" ]; then - var_os="debian" - fi - if [ -z "$var_version" ]; then - var_version="12" - fi + # Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts + if [ -z "$var_os" ]; then + var_os="debian" + fi + if [ -z "$var_version" ]; then + var_version="12" + fi } write_config() { - mkdir -p /opt/community-scripts - # This function writes the configuration to a file. - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Write configfile" --yesno "Do you want to write the selections to a config file?" 10 60; then - FILEPATH="/opt/community-scripts/${NSAPP}.conf" - if [[ ! -f $FILEPATH ]]; then - cat <"$FILEPATH" + mkdir -p /opt/community-scripts + # This function writes the configuration to a file. + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Write configfile" --yesno "Do you want to write the selections to a config file?" 10 60; then + FILEPATH="/opt/community-scripts/${NSAPP}.conf" + if [[ ! -f $FILEPATH ]]; then + cat <"$FILEPATH" # ${NSAPP} Configuration File # Generated on $(date) @@ -382,12 +382,12 @@ NET="${NET}" FUSE="${ENABLE_FUSE}" EOF - echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" - else - echo -e "${INFO}${BOLD}${RD}Configuration file already exists at ${FILEPATH}${CL}" - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Overwrite configfile" --yesno "Do you want to overwrite the existing config file?" 10 60; then - rm -f "$FILEPATH" - cat <"$FILEPATH" + echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" + else + echo -e "${INFO}${BOLD}${RD}Configuration file already exists at ${FILEPATH}${CL}" + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "Overwrite configfile" --yesno "Do you want to overwrite the existing config file?" 10 60; then + rm -f "$FILEPATH" + cat <"$FILEPATH" # ${NSAPP} Configuration File # Generated on $(date) @@ -414,518 +414,518 @@ NET="${NET}" FUSE="${ENABLE_FUSE}" EOF - echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" - else - echo -e "${INFO}${BOLD}${RD}Configuration file not overwritten${CL}" - fi - fi + echo -e "${INFO}${BOLD}${GN}Writing configuration to ${FILEPATH}${CL}" + else + echo -e "${INFO}${BOLD}${RD}Configuration file not overwritten${CL}" + fi fi + fi } # This function displays the default values for various settings. echo_default() { - # Convert CT_TYPE to description - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi + # Convert CT_TYPE to description + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi - # Output the selected values with icons - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os ($var_version)${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" - echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - if [ "$VERB" == "yes" ]; then - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}" - fi - echo -e "${CREATING}${BOLD}${BL}Creating a ${APP} LXC using the above default settings${CL}" - echo -e " " + # Output the selected values with icons + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os ($var_version)${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" + echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" + echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" + if [ "$VERB" == "yes" ]; then + echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}" + fi + echo -e "${CREATING}${BOLD}${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e " " } # This function is called when the user decides to exit the script. It clears the screen and displays an exit message. exit_script() { - clear - echo -e "\n${CROSS}${RD}User exited script${CL}\n" - exit + clear + echo -e "\n${CROSS}${RD}User exited script${CL}\n" + exit } # This function allows the user to configure advanced settings for the script. advanced_settings() { - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 - # Setting Default Tag for Advanced Settings - TAGS="community-script;${var_tags:-}" - CT_DEFAULT_TYPE="${CT_TYPE}" - CT_TYPE="" - while [ -z "$CT_TYPE" ]; do - if [ "$CT_DEFAULT_TYPE" == "1" ]; then - if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - if [ -n "$CT_TYPE" ]; then - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os | ${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - fi - else - exit_script - fi + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 + # Setting Default Tag for Advanced Settings + TAGS="community-script;${var_tags:-}" + CT_DEFAULT_TYPE="${CT_TYPE}" + CT_TYPE="" + while [ -z "$CT_TYPE" ]; do + if [ "$CT_DEFAULT_TYPE" == "1" ]; then + if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then + if [ -n "$CT_TYPE" ]; then + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os | ${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" fi - if [ "$CT_DEFAULT_TYPE" == "0" ]; then - if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3); then - if [ -n "$CT_TYPE" ]; then - CT_TYPE_DESC="Unprivileged" - if [ "$CT_TYPE" -eq 0 ]; then - CT_TYPE_DESC="Privileged" - fi - echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" - echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" - fi - else - exit_script - fi - fi - done - - while true; do - if PW1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD (leave blank for automatic login)" 3>&1 1>&2 2>&3); then - # Empty = Autologin - if [[ -z "$PW1" ]]; then - PW="" - PW1="Automatic Login" - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}$PW1${CL}" - break - fi - - # Invalid: contains spaces - if [[ "$PW1" == *" "* ]]; then - whiptail --msgbox "Password cannot contain spaces." 8 58 - continue - fi - - # Invalid: too short - if ((${#PW1} < 5)); then - whiptail --msgbox "Password must be at least 5 characters." 8 58 - continue - fi - - # Confirm password - if PW2=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nVerify Root Password" 9 58 --title "PASSWORD VERIFICATION" 3>&1 1>&2 2>&3); then - if [[ "$PW1" == "$PW2" ]]; then - PW="-password $PW1" - echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}********${CL}" - break - else - whiptail --msgbox "Passwords do not match. Please try again." 8 58 - fi - else - exit_script - fi - else - exit_script - fi - done - - if CT_ID=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 "$NEXTID" --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi - else + else exit_script + fi fi - - while true; do - if CT_NAME=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 "$NSAPP" --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo "${CT_NAME,,}" | tr -d ' ') - fi - # Hostname validate (RFC 1123) - if [[ "$HN" =~ ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ ]]; then - echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}" - break - else - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --msgbox "❌ Invalid hostname: '$HN'\n\nOnly lowercase letters, digits and hyphens (-) are allowed.\nUnderscores (_) or other characters are not permitted!" 10 70 - fi - else - exit_script + if [ "$CT_DEFAULT_TYPE" == "0" ]; then + if CT_TYPE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3); then + if [ -n "$CT_TYPE" ]; then + CT_TYPE_DESC="Unprivileged" + if [ "$CT_TYPE" -eq 0 ]; then + CT_TYPE_DESC="Privileged" + fi + echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}" + echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" fi - done - - while true; do - DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GB" 8 58 "$var_disk" --title "DISK SIZE" 3>&1 1>&2 2>&3) || exit_script - - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - fi - - if [[ "$DISK_SIZE" =~ ^[1-9][0-9]*$ ]]; then - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" - break - else - whiptail --msgbox "Disk size must be a positive integer!" 8 58 - fi - done - - while true; do - CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ - --inputbox "Allocate CPU Cores" 8 58 "$var_cpu" --title "CORE COUNT" 3>&1 1>&2 2>&3) || exit_script - - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - fi - - if [[ "$CORE_COUNT" =~ ^[1-9][0-9]*$ ]]; then - echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}" - break - else - whiptail --msgbox "CPU core count must be a positive integer!" 8 58 - fi - done - - while true; do - RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ - --inputbox "Allocate RAM in MiB" 8 58 "$var_ram" --title "RAM" 3>&1 1>&2 2>&3) || exit_script - - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - fi - - if [[ "$RAM_SIZE" =~ ^[1-9][0-9]*$ ]]; then - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" - break - else - whiptail --msgbox "RAM size must be a positive integer!" 8 58 - fi - done - - IFACE_FILEPATH_LIST="/etc/network/interfaces"$'\n'$(find "/etc/network/interfaces.d/" -type f) - BRIDGES="" - OLD_IFS=$IFS - IFS=$'\n' - for iface_filepath in ${IFACE_FILEPATH_LIST}; do - - iface_indexes_tmpfile=$(mktemp -q -u '.iface-XXXX') - (grep -Pn '^\s*iface' "${iface_filepath}" | cut -d':' -f1 && wc -l "${iface_filepath}" | cut -d' ' -f1) | awk 'FNR==1 {line=$0; next} {print line":"$0-1; line=$0}' >"${iface_indexes_tmpfile}" || true - - if [ -f "${iface_indexes_tmpfile}" ]; then - - while read -r pair; do - start=$(echo "${pair}" | cut -d':' -f1) - end=$(echo "${pair}" | cut -d':' -f2) - - if awk "NR >= ${start} && NR <= ${end}" "${iface_filepath}" | grep -qP '^\s*(bridge[-_](ports|stp|fd|vlan-aware|vids)|ovs_type\s+OVSBridge)\b'; then - iface_name=$(sed "${start}q;d" "${iface_filepath}" | awk '{print $2}') - BRIDGES="${iface_name}"$'\n'"${BRIDGES}" - fi - - done <"${iface_indexes_tmpfile}" - rm -f "${iface_indexes_tmpfile}" - fi - - done - IFS=$OLD_IFS - BRIDGES=$(echo "$BRIDGES" | grep -v '^\s*$' | sort | uniq) - if [[ -z "$BRIDGES" ]]; then - BRG="vmbr0" - echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" - else - BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --menu "Select network bridge:" 15 40 6 $(echo "$BRIDGES" | awk '{print $0, "Bridge"}') 3>&1 1>&2 2>&3) - if [[ -z "$BRG" ]]; then - exit_script - else - echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" - fi - fi - - # IPv4 methods: dhcp, static, none - while true; do - IPV4_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --title "IPv4 Address Management" \ - --menu "Select IPv4 Address Assignment Method:" 12 60 2 \ - "dhcp" "Automatic (DHCP, recommended)" \ - "static" "Static (manual entry)" \ - 3>&1 1>&2 2>&3) - - exit_status=$? - if [ $exit_status -ne 0 ]; then - exit_script - fi - - case "$IPV4_METHOD" in - dhcp) - NET="dhcp" - GATE="" - echo -e "${NETWORK}${BOLD}${DGN}IPv4: DHCP${CL}" - break - ;; - static) - # Static: call and validate CIDR address - while true; do - NET=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --inputbox "Enter Static IPv4 CIDR Address (e.g. 192.168.100.50/24)" 8 58 "" \ - --title "IPv4 ADDRESS" 3>&1 1>&2 2>&3) - if [ -z "$NET" ]; then - whiptail --msgbox "IPv4 address must not be empty." 8 58 - continue - elif [[ "$NET" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then - echo -e "${NETWORK}${BOLD}${DGN}IPv4 Address: ${BGN}$NET${CL}" - break - else - whiptail --msgbox "$NET is not a valid IPv4 CIDR address. Please enter a correct value!" 8 58 - fi - done - - # call and validate Gateway - while true; do - GATE1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --inputbox "Enter Gateway IP address for static IPv4" 8 58 "" \ - --title "Gateway IP" 3>&1 1>&2 2>&3) - if [ -z "$GATE1" ]; then - whiptail --msgbox "Gateway IP address cannot be empty." 8 58 - elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then - whiptail --msgbox "Invalid Gateway IP address format." 8 58 - else - GATE=",gw=$GATE1" - echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}$GATE1${CL}" - break - fi - done - break - ;; - esac - done - - # IPv6 Address Management selection - while true; do - IPV6_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --menu \ - "Select IPv6 Address Management Type:" 15 58 4 \ - "auto" "SLAAC/AUTO (recommended, default)" \ - "dhcp" "DHCPv6" \ - "static" "Static (manual entry)" \ - "none" "Disabled" \ - --default-item "auto" 3>&1 1>&2 2>&3) - [ $? -ne 0 ] && exit_script - - case "$IPV6_METHOD" in - auto) - echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}SLAAC/AUTO${CL}" - IPV6_ADDR="" - IPV6_GATE="" - break - ;; - dhcp) - echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}DHCPv6${CL}" - IPV6_ADDR="dhcp" - IPV6_GATE="" - break - ;; - static) - # Ask for static IPv6 address (CIDR notation, e.g., 2001:db8::1234/64) - while true; do - IPV6_ADDR=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ - "Set a static IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 "" \ - --title "IPv6 STATIC ADDRESS" 3>&1 1>&2 2>&3) || exit_script - if [[ "$IPV6_ADDR" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+(/[0-9]{1,3})$ ]]; then - echo -e "${NETWORK}${BOLD}${DGN}IPv6 Address: ${BGN}$IPV6_ADDR${CL}" - break - else - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ - "$IPV6_ADDR is an invalid IPv6 CIDR address. Please enter a valid IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 - fi - done - # Optional: ask for IPv6 gateway for static config - while true; do - IPV6_GATE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ - "Enter IPv6 gateway address (optional, leave blank for none)" 8 58 "" --title "IPv6 GATEWAY" 3>&1 1>&2 2>&3) - if [ -z "$IPV6_GATE" ]; then - IPV6_GATE="" - break - elif [[ "$IPV6_GATE" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+$ ]]; then - break - else - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ - "Invalid IPv6 gateway format." 8 58 - fi - done - break - ;; - none) - echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}Disabled${CL}" - IPV6_ADDR="none" - IPV6_GATE="" - break - ;; - *) - exit_script - ;; - esac - done - - if [ "$var_os" == "alpine" ]; then - APT_CACHER="" - APT_CACHER_IP="" - else - if APT_CACHER_IP=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for none)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then - APT_CACHER="${APT_CACHER_IP:+yes}" - echo -e "${NETWORK}${BOLD}${DGN}APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" - else - exit_script - fi - fi - - # if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - # DISABLEIP6="yes" - # else - # DISABLEIP6="no" - # fi - # echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - - if MTU1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default [The MTU of your selected vmbr, default is 1500])" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$MTU1" ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}" - else + else exit_script + fi fi + done - if SD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z "$SD" ]; then - SX=Host - SD="" + while true; do + if PW1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD (leave blank for automatic login)" 3>&1 1>&2 2>&3); then + # Empty = Autologin + if [[ -z "$PW1" ]]; then + PW="" + PW1="Automatic Login" + echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}$PW1${CL}" + break + fi + + # Invalid: contains spaces + if [[ "$PW1" == *" "* ]]; then + whiptail --msgbox "Password cannot contain spaces." 8 58 + continue + fi + + # Invalid: too short + if ((${#PW1} < 5)); then + whiptail --msgbox "Password must be at least 5 characters." 8 58 + continue + fi + + # Confirm password + if PW2=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --passwordbox "\nVerify Root Password" 9 58 --title "PASSWORD VERIFICATION" 3>&1 1>&2 2>&3); then + if [[ "$PW1" == "$PW2" ]]; then + PW="-password $PW1" + echo -e "${VERIFYPW}${BOLD}${DGN}Root Password: ${BGN}********${CL}" + break else - SX=$SD - SD="-searchdomain=$SD" + whiptail --msgbox "Passwords do not match. Please try again." 8 58 fi - echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}$SX${CL}" - else + else exit_script + fi + else + exit_script + fi + done + + if CT_ID=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 "$NEXTID" --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi + else + exit_script + fi + + while true; do + if CT_NAME=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 "$NSAPP" --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo "${CT_NAME,,}" | tr -d ' ') + fi + # Hostname validate (RFC 1123) + if [[ "$HN" =~ ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ ]]; then + echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}" + break + else + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --msgbox "❌ Invalid hostname: '$HN'\n\nOnly lowercase letters, digits and hyphens (-) are allowed.\nUnderscores (_) or other characters are not permitted!" 10 70 + fi + else + exit_script + fi + done + + while true; do + DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GB" 8 58 "$var_disk" --title "DISK SIZE" 3>&1 1>&2 2>&3) || exit_script + + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" fi - if NX=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z "$NX" ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" + if [[ "$DISK_SIZE" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" + break + else + whiptail --msgbox "Disk size must be a positive integer!" 8 58 + fi + done + + while true; do + CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ + --inputbox "Allocate CPU Cores" 8 58 "$var_cpu" --title "CORE COUNT" 3>&1 1>&2 2>&3) || exit_script + + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + fi + + if [[ "$CORE_COUNT" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}" + break + else + whiptail --msgbox "CPU core count must be a positive integer!" 8 58 + fi + done + + while true; do + RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" \ + --inputbox "Allocate RAM in MiB" 8 58 "$var_ram" --title "RAM" 3>&1 1>&2 2>&3) || exit_script + + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + fi + + if [[ "$RAM_SIZE" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" + break + else + whiptail --msgbox "RAM size must be a positive integer!" 8 58 + fi + done + + IFACE_FILEPATH_LIST="/etc/network/interfaces"$'\n'$(find "/etc/network/interfaces.d/" -type f) + BRIDGES="" + OLD_IFS=$IFS + IFS=$'\n' + for iface_filepath in ${IFACE_FILEPATH_LIST}; do + + iface_indexes_tmpfile=$(mktemp -q -u '.iface-XXXX') + (grep -Pn '^\s*iface' "${iface_filepath}" | cut -d':' -f1 && wc -l "${iface_filepath}" | cut -d' ' -f1) | awk 'FNR==1 {line=$0; next} {print line":"$0-1; line=$0}' >"${iface_indexes_tmpfile}" || true + + if [ -f "${iface_indexes_tmpfile}" ]; then + + while read -r pair; do + start=$(echo "${pair}" | cut -d':' -f1) + end=$(echo "${pair}" | cut -d':' -f2) + + if awk "NR >= ${start} && NR <= ${end}" "${iface_filepath}" | grep -qP '^\s*(bridge[-_](ports|stp|fd|vlan-aware|vids)|ovs_type\s+OVSBridge)\b'; then + iface_name=$(sed "${start}q;d" "${iface_filepath}" | awk '{print $2}') + BRIDGES="${iface_name}"$'\n'"${BRIDGES}" fi - echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}$NX${CL}" - else - exit_script + + done <"${iface_indexes_tmpfile}" + rm -f "${iface_indexes_tmpfile}" fi - if [ "$var_os" == "alpine" ] && [ "$NET" == "dhcp" ] && [ "$NX" != "Host" ]; then - UDHCPC_FIX="yes" + done + IFS=$OLD_IFS + BRIDGES=$(echo "$BRIDGES" | grep -v '^\s*$' | sort | uniq) + if [[ -z "$BRIDGES" ]]; then + BRG="vmbr0" + echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" + else + BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --menu "Select network bridge:" 15 40 6 $(echo "$BRIDGES" | awk '{print $0, "Bridge"}') 3>&1 1>&2 2>&3) + if [[ -z "$BRG" ]]; then + exit_script else - UDHCPC_FIX="no" + echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}" fi - export UDHCPC_FIX + fi - if MAC1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a MAC Address(leave blank for generated MAC)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z "$MAC1" ]; then - MAC1="Default" - MAC="" + # IPv4 methods: dhcp, static, none + while true; do + IPV4_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --title "IPv4 Address Management" \ + --menu "Select IPv4 Address Assignment Method:" 12 60 2 \ + "dhcp" "Automatic (DHCP, recommended)" \ + "static" "Static (manual entry)" \ + 3>&1 1>&2 2>&3) + + exit_status=$? + if [ $exit_status -ne 0 ]; then + exit_script + fi + + case "$IPV4_METHOD" in + dhcp) + NET="dhcp" + GATE="" + echo -e "${NETWORK}${BOLD}${DGN}IPv4: DHCP${CL}" + break + ;; + static) + # Static: call and validate CIDR address + while true; do + NET=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --inputbox "Enter Static IPv4 CIDR Address (e.g. 192.168.100.50/24)" 8 58 "" \ + --title "IPv4 ADDRESS" 3>&1 1>&2 2>&3) + if [ -z "$NET" ]; then + whiptail --msgbox "IPv4 address must not be empty." 8 58 + continue + elif [[ "$NET" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then + echo -e "${NETWORK}${BOLD}${DGN}IPv4 Address: ${BGN}$NET${CL}" + break else - MAC=",hwaddr=$MAC1" - echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}" + whiptail --msgbox "$NET is not a valid IPv4 CIDR address. Please enter a correct value!" 8 58 fi - else - exit_script - fi + done - if VLAN1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for no VLAN)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z "$VLAN1" ]; then - VLAN1="Default" - VLAN="" + # call and validate Gateway + while true; do + GATE1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --inputbox "Enter Gateway IP address for static IPv4" 8 58 "" \ + --title "Gateway IP" 3>&1 1>&2 2>&3) + if [ -z "$GATE1" ]; then + whiptail --msgbox "Gateway IP address cannot be empty." 8 58 + elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + whiptail --msgbox "Invalid Gateway IP address format." 8 58 else - VLAN=",tag=$VLAN1" + GATE=",gw=$GATE1" + echo -e "${GATEWAY}${BOLD}${DGN}Gateway IP Address: ${BGN}$GATE1${CL}" + break fi - echo -e "${VLANTAG}${BOLD}${DGN}Vlan: ${BGN}$VLAN1${CL}" - else - exit_script - fi + done + break + ;; + esac + done - if ADV_TAGS=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Custom Tags?[If you remove all, there will be no tags!]" 8 58 "${TAGS}" --title "Advanced Tags" 3>&1 1>&2 2>&3); then - if [ -n "${ADV_TAGS}" ]; then - ADV_TAGS=$(echo "$ADV_TAGS" | tr -d '[:space:]') - TAGS="${ADV_TAGS}" + # IPv6 Address Management selection + while true; do + IPV6_METHOD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --menu \ + "Select IPv6 Address Management Type:" 15 58 4 \ + "auto" "SLAAC/AUTO (recommended, default)" \ + "dhcp" "DHCPv6" \ + "static" "Static (manual entry)" \ + "none" "Disabled" \ + --default-item "auto" 3>&1 1>&2 2>&3) + [ $? -ne 0 ] && exit_script + + case "$IPV6_METHOD" in + auto) + echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}SLAAC/AUTO${CL}" + IPV6_ADDR="" + IPV6_GATE="" + break + ;; + dhcp) + echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}DHCPv6${CL}" + IPV6_ADDR="dhcp" + IPV6_GATE="" + break + ;; + static) + # Ask for static IPv6 address (CIDR notation, e.g., 2001:db8::1234/64) + while true; do + IPV6_ADDR=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ + "Set a static IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 "" \ + --title "IPv6 STATIC ADDRESS" 3>&1 1>&2 2>&3) || exit_script + if [[ "$IPV6_ADDR" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+(/[0-9]{1,3})$ ]]; then + echo -e "${NETWORK}${BOLD}${DGN}IPv6 Address: ${BGN}$IPV6_ADDR${CL}" + break else - TAGS=";" + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ + "$IPV6_ADDR is an invalid IPv6 CIDR address. Please enter a valid IPv6 CIDR address (e.g., 2001:db8::1234/64)" 8 58 fi - echo -e "${NETWORK}${BOLD}${DGN}Tags: ${BGN}$TAGS${CL}" - else - exit_script - fi - - SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "SSH Authorized key for root (leave empty for none)" 8 58 --title "SSH Key" 3>&1 1>&2 2>&3)" - - if [[ -z "${SSH_AUTHORIZED_KEY}" ]]; then - SSH_AUTHORIZED_KEY="" - fi - - if [[ "$PW" == -password* || -n "$SSH_AUTHORIZED_KEY" ]]; then - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" + done + # Optional: ask for IPv6 gateway for static config + while true; do + IPV6_GATE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox \ + "Enter IPv6 gateway address (optional, leave blank for none)" 8 58 "" --title "IPv6 GATEWAY" 3>&1 1>&2 2>&3) + if [ -z "$IPV6_GATE" ]; then + IPV6_GATE="" + break + elif [[ "$IPV6_GATE" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+$ ]]; then + break else - SSH="no" + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox \ + "Invalid IPv6 gateway format." 8 58 fi - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - else - SSH="no" - echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" - fi + done + break + ;; + none) + echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}Disabled${CL}" + IPV6_ADDR="none" + IPV6_GATE="" + break + ;; + *) + exit_script + ;; + esac + done - if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "FUSE Support" --yesno "Enable FUSE support?\nRequired for tools like rclone, mergerfs, AppImage, etc." 10 58); then - ENABLE_FUSE="yes" + if [ "$var_os" == "alpine" ]; then + APT_CACHER="" + APT_CACHER_IP="" + else + if APT_CACHER_IP=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for none)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then + APT_CACHER="${APT_CACHER_IP:+yes}" + echo -e "${NETWORK}${BOLD}${DGN}APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" else - ENABLE_FUSE="no" + exit_script fi - echo -e "${FUSE}${BOLD}${DGN}Enable FUSE Support: ${BGN}$ENABLE_FUSE${CL}" + fi - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERBOSE="yes" - else - VERBOSE="no" - fi - echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERBOSE${CL}" + # if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + # DISABLEIP6="yes" + # else + # DISABLEIP6="no" + # fi + # echo -e "${DISABLEIPV6}${BOLD}${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - write_config + if MTU1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default [The MTU of your selected vmbr, default is 1500])" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$MTU1" ]; then + MTU1="Default" + MTU="" else - clear - header_info - echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" - advanced_settings + MTU=",mtu=$MTU1" fi + echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}" + else + exit_script + fi + + if SD=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then + if [ -z "$SD" ]; then + SX=Host + SD="" + else + SX=$SD + SD="-searchdomain=$SD" + fi + echo -e "${SEARCH}${BOLD}${DGN}DNS Search Domain: ${BGN}$SX${CL}" + else + exit_script + fi + + if NX=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z "$NX" ]; then + NX=Host + NS="" + else + NS="-nameserver=$NX" + fi + echo -e "${NETWORK}${BOLD}${DGN}DNS Server IP Address: ${BGN}$NX${CL}" + else + exit_script + fi + + if [ "$var_os" == "alpine" ] && [ "$NET" == "dhcp" ] && [ "$NX" != "Host" ]; then + UDHCPC_FIX="yes" + else + UDHCPC_FIX="no" + fi + export UDHCPC_FIX + + if MAC1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a MAC Address(leave blank for generated MAC)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z "$MAC1" ]; then + MAC1="Default" + MAC="" + else + MAC=",hwaddr=$MAC1" + echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}" + fi + else + exit_script + fi + + if VLAN1=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for no VLAN)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then + if [ -z "$VLAN1" ]; then + VLAN1="Default" + VLAN="" + else + VLAN=",tag=$VLAN1" + fi + echo -e "${VLANTAG}${BOLD}${DGN}Vlan: ${BGN}$VLAN1${CL}" + else + exit_script + fi + + if ADV_TAGS=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "Set Custom Tags?[If you remove all, there will be no tags!]" 8 58 "${TAGS}" --title "Advanced Tags" 3>&1 1>&2 2>&3); then + if [ -n "${ADV_TAGS}" ]; then + ADV_TAGS=$(echo "$ADV_TAGS" | tr -d '[:space:]') + TAGS="${ADV_TAGS}" + else + TAGS=";" + fi + echo -e "${NETWORK}${BOLD}${DGN}Tags: ${BGN}$TAGS${CL}" + else + exit_script + fi + + SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "SSH Authorized key for root (leave empty for none)" 8 58 --title "SSH Key" 3>&1 1>&2 2>&3)" + + if [[ -z "${SSH_AUTHORIZED_KEY}" ]]; then + SSH_AUTHORIZED_KEY="" + fi + + if [[ "$PW" == -password* || -n "$SSH_AUTHORIZED_KEY" ]]; then + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" + else + SSH="no" + fi + echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" + else + SSH="no" + echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}" + fi + + if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "FUSE Support" --yesno "Enable FUSE support?\nRequired for tools like rclone, mergerfs, AppImage, etc." 10 58); then + ENABLE_FUSE="yes" + else + ENABLE_FUSE="no" + fi + echo -e "${FUSE}${BOLD}${DGN}Enable FUSE Support: ${BGN}$ENABLE_FUSE${CL}" + + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERBOSE="yes" + else + VERBOSE="no" + fi + echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERBOSE${CL}" + + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + write_config + else + clear + header_info + echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" + advanced_settings + fi } diagnostics_check() { - if ! [ -d "/usr/local/community-scripts" ]; then - mkdir -p /usr/local/community-scripts - fi + if ! [ -d "/usr/local/community-scripts" ]; then + mkdir -p /usr/local/community-scripts + fi - if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then - if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then - cat </usr/local/community-scripts/diagnostics + if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then + if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then + cat </usr/local/community-scripts/diagnostics DIAGNOSTICS=yes #This file is used to store the diagnostics settings for the Community-Scripts API. @@ -950,9 +950,9 @@ DIAGNOSTICS=yes #"status" #If you have any concerns, please review the source code at /misc/build.func EOF - DIAGNOSTICS="yes" - else - cat </usr/local/community-scripts/diagnostics + DIAGNOSTICS="yes" + else + cat </usr/local/community-scripts/diagnostics DIAGNOSTICS=no #This file is used to store the diagnostics settings for the Community-Scripts API. @@ -977,248 +977,248 @@ DIAGNOSTICS=no #"status" #If you have any concerns, please review the source code at /misc/build.func EOF - DIAGNOSTICS="no" - fi - else - DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' /usr/local/community-scripts/diagnostics) - + DIAGNOSTICS="no" fi + else + DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' /usr/local/community-scripts/diagnostics) + + fi } install_script() { - pve_check - shell_check - root_check - arch_check - ssh_check - maxkeys_check - diagnostics_check + pve_check + shell_check + root_check + arch_check + ssh_check + maxkeys_check + diagnostics_check - if systemctl is-active -q ping-instances.service; then - systemctl -q stop ping-instances.service + if systemctl is-active -q ping-instances.service; then + systemctl -q stop ping-instances.service + fi + NEXTID=$(pvesh get /cluster/nextid) + timezone=$(cat /etc/timezone) + header_info + while true; do + + TMP_CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --title "SETTINGS" \ + --menu "Choose an option:" 20 60 7 \ + "1" "Default Settings" \ + "2" "Default Settings (with verbose)" \ + "3" "Advanced Settings" \ + "4" "Use Config File" \ + "5" "Manage Default Storage" \ + "6" "Diagnostic Settings" \ + "7" "Exit" \ + --default-item "1" 3>&1 1>&2 2>&3) || true + + if [ -z "$TMP_CHOICE" ]; then + echo -e "\n${CROSS}${RD}Menu canceled. Exiting script.${CL}\n" + exit 0 fi - NEXTID=$(pvesh get /cluster/nextid) - timezone=$(cat /etc/timezone) - header_info - while true; do - TMP_CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --title "SETTINGS" \ - --menu "Choose an option:" 20 60 7 \ - "1" "Default Settings" \ - "2" "Default Settings (with verbose)" \ - "3" "Advanced Settings" \ - "4" "Use Config File" \ - "5" "Manage Default Storage" \ - "6" "Diagnostic Settings" \ - "7" "Exit" \ - --default-item "1" 3>&1 1>&2 2>&3) || true + CHOICE="$TMP_CHOICE" - if [ -z "$TMP_CHOICE" ]; then - echo -e "\n${CROSS}${RD}Menu canceled. Exiting script.${CL}\n" - exit 0 + case $CHOICE in + 1) + header_info + echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME${CL}" + VERBOSE="no" + METHOD="default" + base_settings "$VERBOSE" + echo_default + break + ;; + 2) + header_info + echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME (${VERBOSE_CROPPED}Verbose)${CL}" + VERBOSE="yes" + METHOD="default" + base_settings "$VERBOSE" + echo_default + break + ;; + 3) + header_info + echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" + METHOD="advanced" + base_settings + advanced_settings + break + ;; + 4) + header_info + echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" + METHOD="advanced" + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/config-file.func) + config_file + break + ;; + + 5) + manage_default_storage + ;; + 6) + if [[ $DIAGNOSTICS == "yes" ]]; then + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ + --yes-button "No" --no-button "Back"; then + DIAGNOSTICS="no" + sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 fi - - CHOICE="$TMP_CHOICE" - - case $CHOICE in - 1) - header_info - echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME${CL}" - VERBOSE="no" - METHOD="default" - base_settings "$VERBOSE" - echo_default - break - ;; - 2) - header_info - echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME (${VERBOSE_CROPPED}Verbose)${CL}" - VERBOSE="yes" - METHOD="default" - base_settings "$VERBOSE" - echo_default - break - ;; - 3) - header_info - echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" - METHOD="advanced" - base_settings - advanced_settings - break - ;; - 4) - header_info - echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" - METHOD="advanced" - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/config-file.func) - config_file - break - ;; - - 5) - manage_default_storage - ;; - 6) - if [[ $DIAGNOSTICS == "yes" ]]; then - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ - --yes-button "No" --no-button "Back"; then - DIAGNOSTICS="no" - sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 - fi - else - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ - --yes-button "Yes" --no-button "Back"; then - DIAGNOSTICS="yes" - sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 - fi - fi - ;; - 7) - echo -e "\n${CROSS}${RD}Script terminated. Have a great day!${CL}\n" - exit 0 - ;; - *) - echo -e "${CROSS}${RD}Invalid option, please try again.${CL}" - ;; - esac - done + else + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ + --yes-button "Yes" --no-button "Back"; then + DIAGNOSTICS="yes" + sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 + fi + fi + ;; + 7) + echo -e "\n${CROSS}${RD}Script terminated. Have a great day!${CL}\n" + exit 0 + ;; + *) + echo -e "${CROSS}${RD}Invalid option, please try again.${CL}" + ;; + esac + done } check_container_resources() { - # Check actual RAM & Cores - current_ram=$(free -m | awk 'NR==2{print $2}') - current_cpu=$(nproc) + # Check actual RAM & Cores + current_ram=$(free -m | awk 'NR==2{print $2}') + current_cpu=$(nproc) - # Check whether the current RAM is less than the required RAM or the CPU cores are less than required - if [[ "$current_ram" -lt "$var_ram" ]] || [[ "$current_cpu" -lt "$var_cpu" ]]; then - echo -e "\n${INFO}${HOLD} ${GN}Required: ${var_cpu} CPU, ${var_ram}MB RAM ${CL}| ${RD}Current: ${current_cpu} CPU, ${current_ram}MB RAM${CL}" - echo -e "${YWB}Please ensure that the ${APP} LXC is configured with at least ${var_cpu} vCPU and ${var_ram} MB RAM for the build process.${CL}\n" - echo -ne "${INFO}${HOLD} May cause data loss! ${INFO} Continue update with under-provisioned LXC? " - read -r prompt - # Check if the input is 'yes', otherwise exit with status 1 - if [[ ! ${prompt,,} =~ ^(yes)$ ]]; then - echo -e "${CROSS}${HOLD} ${YWB}Exiting based on user input.${CL}" - exit 1 - fi - else - echo -e "" + # Check whether the current RAM is less than the required RAM or the CPU cores are less than required + if [[ "$current_ram" -lt "$var_ram" ]] || [[ "$current_cpu" -lt "$var_cpu" ]]; then + echo -e "\n${INFO}${HOLD} ${GN}Required: ${var_cpu} CPU, ${var_ram}MB RAM ${CL}| ${RD}Current: ${current_cpu} CPU, ${current_ram}MB RAM${CL}" + echo -e "${YWB}Please ensure that the ${APP} LXC is configured with at least ${var_cpu} vCPU and ${var_ram} MB RAM for the build process.${CL}\n" + echo -ne "${INFO}${HOLD} May cause data loss! ${INFO} Continue update with under-provisioned LXC? " + read -r prompt + # Check if the input is 'yes', otherwise exit with status 1 + if [[ ! ${prompt,,} =~ ^(yes)$ ]]; then + echo -e "${CROSS}${HOLD} ${YWB}Exiting based on user input.${CL}" + exit 1 fi + else + echo -e "" + fi } check_container_storage() { - # Check if the /boot partition is more than 80% full - total_size=$(df /boot --output=size | tail -n 1) - local used_size=$(df /boot --output=used | tail -n 1) - usage=$((100 * used_size / total_size)) - if ((usage > 80)); then - # Prompt the user for confirmation to continue - echo -e "${INFO}${HOLD} ${YWB}Warning: Storage is dangerously low (${usage}%).${CL}" - echo -ne "Continue anyway? " - read -r prompt - # Check if the input is 'y' or 'yes', otherwise exit with status 1 - if [[ ! ${prompt,,} =~ ^(y|yes)$ ]]; then - echo -e "${CROSS}${HOLD}${YWB}Exiting based on user input.${CL}" - exit 1 - fi + # Check if the /boot partition is more than 80% full + total_size=$(df /boot --output=size | tail -n 1) + local used_size=$(df /boot --output=used | tail -n 1) + usage=$((100 * used_size / total_size)) + if ((usage > 80)); then + # Prompt the user for confirmation to continue + echo -e "${INFO}${HOLD} ${YWB}Warning: Storage is dangerously low (${usage}%).${CL}" + echo -ne "Continue anyway? " + read -r prompt + # Check if the input is 'y' or 'yes', otherwise exit with status 1 + if [[ ! ${prompt,,} =~ ^(y|yes)$ ]]; then + echo -e "${CROSS}${HOLD}${YWB}Exiting based on user input.${CL}" + exit 1 fi + fi } start() { - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) - if command -v pveversion >/dev/null 2>&1; then - install_script - elif [ ! -z ${PHS_SILENT+x} ] && [[ "${PHS_SILENT}" == "1" ]]; then - VERBOSE="no" - set_std_mode - update_script - else - CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC Update/Setting" --menu \ - "Support/Update functions for ${APP} LXC. Choose an option:" \ - 12 60 3 \ - "1" "YES (Silent Mode)" \ - "2" "YES (Verbose Mode)" \ - "3" "NO (Cancel Update)" --nocancel --default-item "1" 3>&1 1>&2 2>&3) + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) + if command -v pveversion >/dev/null 2>&1; then + install_script + elif [ ! -z ${PHS_SILENT+x} ] && [[ "${PHS_SILENT}" == "1" ]]; then + VERBOSE="no" + set_std_mode + update_script + else + CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "${APP} LXC Update/Setting" --menu \ + "Support/Update functions for ${APP} LXC. Choose an option:" \ + 12 60 3 \ + "1" "YES (Silent Mode)" \ + "2" "YES (Verbose Mode)" \ + "3" "NO (Cancel Update)" --nocancel --default-item "1" 3>&1 1>&2 2>&3) - case "$CHOICE" in - 1) - VERBOSE="no" - set_std_mode - ;; - 2) - VERBOSE="yes" - set_std_mode - ;; - 3) - clear - exit_script - exit - ;; - esac - update_script - fi + case "$CHOICE" in + 1) + VERBOSE="no" + set_std_mode + ;; + 2) + VERBOSE="yes" + set_std_mode + ;; + 3) + clear + exit_script + exit + ;; + esac + update_script + fi } # This function collects user settings and integrates all the collected information. build_container() { - # if [ "$VERBOSE" == "yes" ]; then set -x; fi + # if [ "$VERBOSE" == "yes" ]; then set -x; fi - NET_STRING="-net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU" - case "$IPV6_METHOD" in - auto) NET_STRING="$NET_STRING,ip6=auto" ;; - dhcp) NET_STRING="$NET_STRING,ip6=dhcp" ;; - static) - NET_STRING="$NET_STRING,ip6=$IPV6_ADDR" - [ -n "$IPV6_GATE" ] && NET_STRING="$NET_STRING,gw6=$IPV6_GATE" - ;; - none) ;; - esac + NET_STRING="-net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU" + case "$IPV6_METHOD" in + auto) NET_STRING="$NET_STRING,ip6=auto" ;; + dhcp) NET_STRING="$NET_STRING,ip6=dhcp" ;; + static) + NET_STRING="$NET_STRING,ip6=$IPV6_ADDR" + [ -n "$IPV6_GATE" ] && NET_STRING="$NET_STRING,gw6=$IPV6_GATE" + ;; + none) ;; + esac - if [ "$CT_TYPE" == "1" ]; then - FEATURES="keyctl=1,nesting=1" - else - FEATURES="nesting=1" - fi + if [ "$CT_TYPE" == "1" ]; then + FEATURES="keyctl=1,nesting=1" + else + FEATURES="nesting=1" + fi - if [ "$ENABLE_FUSE" == "yes" ]; then - FEATURES="$FEATURES,fuse=1" - fi + if [ "$ENABLE_FUSE" == "yes" ]; then + FEATURES="$FEATURES,fuse=1" + fi - #if [[ $DIAGNOSTICS == "yes" ]]; then - # post_to_api - #fi + #if [[ $DIAGNOSTICS == "yes" ]]; then + # post_to_api + #fi - TEMP_DIR=$(mktemp -d) - pushd "$TEMP_DIR" >/dev/null - if [ "$var_os" == "alpine" ]; then - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)" - else - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)" - fi - export DIAGNOSTICS="$DIAGNOSTICS" - export RANDOM_UUID="$RANDOM_UUID" - export CACHER="$APT_CACHER" - export CACHER_IP="$APT_CACHER_IP" - export tz="$timezone" - #export DISABLEIPV6="$DISABLEIP6" - export APPLICATION="$APP" - export app="$NSAPP" - export PASSWORD="$PW" - export VERBOSE="$VERBOSE" - export SSH_ROOT="${SSH}" - export SSH_AUTHORIZED_KEY - export CTID="$CT_ID" - export CTTYPE="$CT_TYPE" - export ENABLE_FUSE="$ENABLE_FUSE" - export ENABLE_TUN="$ENABLE_TUN" - export PCT_OSTYPE="$var_os" - export PCT_OSVERSION="$var_version" - export PCT_DISK_SIZE="$DISK_SIZE" - export PCT_OPTIONS=" + TEMP_DIR=$(mktemp -d) + pushd "$TEMP_DIR" >/dev/null + if [ "$var_os" == "alpine" ]; then + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)" + else + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)" + fi + export DIAGNOSTICS="$DIAGNOSTICS" + export RANDOM_UUID="$RANDOM_UUID" + export CACHER="$APT_CACHER" + export CACHER_IP="$APT_CACHER_IP" + export tz="$timezone" + #export DISABLEIPV6="$DISABLEIP6" + export APPLICATION="$APP" + export app="$NSAPP" + export PASSWORD="$PW" + export VERBOSE="$VERBOSE" + export SSH_ROOT="${SSH}" + export SSH_AUTHORIZED_KEY + export CTID="$CT_ID" + export CTTYPE="$CT_TYPE" + export ENABLE_FUSE="$ENABLE_FUSE" + export ENABLE_TUN="$ENABLE_TUN" + export PCT_OSTYPE="$var_os" + export PCT_OSVERSION="$var_version" + export PCT_DISK_SIZE="$DISK_SIZE" + export PCT_OPTIONS=" -features $FEATURES -hostname $HN -tags $TAGS @@ -1231,16 +1231,16 @@ build_container() { -unprivileged $CT_TYPE $PW " - bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)" - if [ $? -ne 0 ]; then - exit 200 - fi + bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)" + if [ $? -ne 0 ]; then + exit 200 + fi - LXC_CONFIG="/etc/pve/lxc/${CTID}.conf" + LXC_CONFIG="/etc/pve/lxc/${CTID}.conf" - # USB passthrough for privileged LXC (CT_TYPE=0) - if [ "$CT_TYPE" == "0" ]; then - cat <>"$LXC_CONFIG" + # USB passthrough for privileged LXC (CT_TYPE=0) + if [ "$CT_TYPE" == "0" ]; then + cat <>"$LXC_CONFIG" # USB passthrough lxc.cgroup2.devices.allow: a lxc.cap.drop: @@ -1252,191 +1252,191 @@ lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create= lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF + fi + + # VAAPI passthrough for privileged containers or known apps + VAAPI_APPS=( + "immich" + "Channels" + "Emby" + "ErsatzTV" + "Frigate" + "Jellyfin" + "Plex" + "Scrypted" + "Tdarr" + "Unmanic" + "Ollama" + "FileFlows" + "Open WebUI" + ) + + is_vaapi_app=false + for vaapi_app in "${VAAPI_APPS[@]}"; do + if [[ "$APP" == "$vaapi_app" ]]; then + is_vaapi_app=true + break + fi + done + + if ([ "$CT_TYPE" == "0" ] || [ "$is_vaapi_app" == "true" ]) && + ([[ -e /dev/dri/renderD128 ]] || [[ -e /dev/dri/card0 ]] || [[ -e /dev/fb0 ]]); then + + echo "" + msg_custom "⚙️ " "\e[96m" "Configuring VAAPI passthrough for LXC container" + if [ "$CT_TYPE" != "0" ]; then + msg_custom "⚠️ " "\e[33m" "Container is unprivileged – VAAPI passthrough may not work without additional host configuration (e.g., idmap)." + fi + msg_custom "ℹ️ " "\e[96m" "VAAPI enables GPU hardware acceleration (e.g., for video transcoding in Jellyfin or Plex)." + echo "" + read -rp "➤ Automatically mount all available VAAPI devices? [Y/n]: " VAAPI_ALL + + if [[ "$VAAPI_ALL" =~ ^[Yy]$|^$ ]]; then + if [ "$CT_TYPE" == "0" ]; then + # PRV Container → alles zulässig + [[ -e /dev/dri/renderD128 ]] && { + echo "lxc.cgroup2.devices.allow: c 226:128 rwm" >>"$LXC_CONFIG" + echo "lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file" >>"$LXC_CONFIG" + } + [[ -e /dev/dri/card0 ]] && { + echo "lxc.cgroup2.devices.allow: c 226:0 rwm" >>"$LXC_CONFIG" + echo "lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file" >>"$LXC_CONFIG" + } + [[ -e /dev/fb0 ]] && { + echo "lxc.cgroup2.devices.allow: c 29:0 rwm" >>"$LXC_CONFIG" + echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >>"$LXC_CONFIG" + } + [[ -d /dev/dri ]] && { + echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG" + } + else + # UNPRV Container → nur devX für UI + [[ -e /dev/dri/card0 ]] && echo "dev0: /dev/dri/card0,gid=44" >>"$LXC_CONFIG" + [[ -e /dev/dri/card1 ]] && echo "dev0: /dev/dri/card1,gid=44" >>"$LXC_CONFIG" + [[ -e /dev/dri/renderD128 ]] && echo "dev1: /dev/dri/renderD128,gid=104" >>"$LXC_CONFIG" + fi fi - # VAAPI passthrough for privileged containers or known apps - VAAPI_APPS=( - "immich" - "Channels" - "Emby" - "ErsatzTV" - "Frigate" - "Jellyfin" - "Plex" - "Scrypted" - "Tdarr" - "Unmanic" - "Ollama" - "FileFlows" - "Open WebUI" - ) - - is_vaapi_app=false - for vaapi_app in "${VAAPI_APPS[@]}"; do - if [[ "$APP" == "$vaapi_app" ]]; then - is_vaapi_app=true - break - fi - done - - if ([ "$CT_TYPE" == "0" ] || [ "$is_vaapi_app" == "true" ]) && - ([[ -e /dev/dri/renderD128 ]] || [[ -e /dev/dri/card0 ]] || [[ -e /dev/fb0 ]]); then - - echo "" - msg_custom "⚙️ " "\e[96m" "Configuring VAAPI passthrough for LXC container" - if [ "$CT_TYPE" != "0" ]; then - msg_custom "⚠️ " "\e[33m" "Container is unprivileged – VAAPI passthrough may not work without additional host configuration (e.g., idmap)." - fi - msg_custom "ℹ️ " "\e[96m" "VAAPI enables GPU hardware acceleration (e.g., for video transcoding in Jellyfin or Plex)." - echo "" - read -rp "➤ Automatically mount all available VAAPI devices? [Y/n]: " VAAPI_ALL - - if [[ "$VAAPI_ALL" =~ ^[Yy]$|^$ ]]; then - if [ "$CT_TYPE" == "0" ]; then - # PRV Container → alles zulässig - [[ -e /dev/dri/renderD128 ]] && { - echo "lxc.cgroup2.devices.allow: c 226:128 rwm" >>"$LXC_CONFIG" - echo "lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file" >>"$LXC_CONFIG" - } - [[ -e /dev/dri/card0 ]] && { - echo "lxc.cgroup2.devices.allow: c 226:0 rwm" >>"$LXC_CONFIG" - echo "lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file" >>"$LXC_CONFIG" - } - [[ -e /dev/fb0 ]] && { - echo "lxc.cgroup2.devices.allow: c 29:0 rwm" >>"$LXC_CONFIG" - echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >>"$LXC_CONFIG" - } - [[ -d /dev/dri ]] && { - echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG" - } - else - # UNPRV Container → nur devX für UI - [[ -e /dev/dri/card0 ]] && echo "dev0: /dev/dri/card0,gid=44" >>"$LXC_CONFIG" - [[ -e /dev/dri/card1 ]] && echo "dev0: /dev/dri/card1,gid=44" >>"$LXC_CONFIG" - [[ -e /dev/dri/renderD128 ]] && echo "dev1: /dev/dri/renderD128,gid=104" >>"$LXC_CONFIG" - fi - fi - + fi + if [ "$CT_TYPE" == "1" ] && [ "$is_vaapi_app" == "true" ]; then + if [[ -e /dev/dri/card0 ]]; then + echo "dev0: /dev/dri/card0,gid=44" >>"$LXC_CONFIG" + elif [[ -e /dev/dri/card1 ]]; then + echo "dev0: /dev/dri/card1,gid=44" >>"$LXC_CONFIG" fi - if [ "$CT_TYPE" == "1" ] && [ "$is_vaapi_app" == "true" ]; then - if [[ -e /dev/dri/card0 ]]; then - echo "dev0: /dev/dri/card0,gid=44" >>"$LXC_CONFIG" - elif [[ -e /dev/dri/card1 ]]; then - echo "dev0: /dev/dri/card1,gid=44" >>"$LXC_CONFIG" - fi - if [[ -e /dev/dri/renderD128 ]]; then - echo "dev1: /dev/dri/renderD128,gid=104" >>"$LXC_CONFIG" - fi + if [[ -e /dev/dri/renderD128 ]]; then + echo "dev1: /dev/dri/renderD128,gid=104" >>"$LXC_CONFIG" fi + fi - # TUN device passthrough - if [ "$ENABLE_TUN" == "yes" ]; then - cat <>"$LXC_CONFIG" + # TUN device passthrough + if [ "$ENABLE_TUN" == "yes" ]; then + cat <>"$LXC_CONFIG" lxc.cgroup2.devices.allow: c 10:200 rwm lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file EOF + fi + + # This starts the container and executes -install.sh + msg_info "Starting LXC Container" + pct start "$CTID" + + # wait for status 'running' + for i in {1..10}; do + if pct status "$CTID" | grep -q "status: running"; then + msg_ok "Startted LXC Container" + break fi + sleep 1 + if [ "$i" -eq 10 ]; then + msg_error "LXC Container did not reach running state" + exit 1 + fi + done - # This starts the container and executes -install.sh - msg_info "Starting LXC Container" - pct start "$CTID" + if [ "$var_os" == "alpine" ]; then + PING_TARGET="1.1.1.1" + else + PING_TARGET="deb.debian.org" + fi - # wait for status 'running' - for i in {1..10}; do - if pct status "$CTID" | grep -q "status: running"; then - msg_ok "Startted LXC Container" - break - fi - sleep 1 - if [ "$i" -eq 10 ]; then - msg_error "LXC Container did not reach running state" - exit 1 - fi - done - - if [ "$var_os" == "alpine" ]; then - PING_TARGET="alpinelinux.org" + msg_info "Waiting for network in LXC container" + for i in {1..10}; do + if pct exec "$CTID" -- ping -c1 -W1 "$PING_TARGET" >/dev/null 2>&1; then + msg_ok "Network in LXC is reachable" + break + fi + if [ "$i" -lt 10 ]; then + msg_warn "No network yet in LXC (try $i/10) – waiting..." + sleep 3 else - PING_TARGET="deb.debian.org" - fi - - msg_info "Waiting for network in LXC container" - for i in {1..10}; do + msg_error "No network in LXC after waiting." + read -r -p "Set fallback DNS (1.1.1.1/8.8.8.8)? [y/N]: " choice + case "$choice" in + [yY]*) + pct set "$CTID" --nameserver 1.1.1.1 + pct set "$CTID" --nameserver 8.8.8.8 if pct exec "$CTID" -- ping -c1 -W1 "$PING_TARGET" >/dev/null 2>&1; then - msg_ok "Network in LXC is reachable" - break - fi - if [ "$i" -lt 10 ]; then - msg_warn "No network yet in LXC (try $i/10) – waiting..." - sleep 3 + msg_ok "Network reachable after DNS fallback" else - msg_error "No network in LXC after waiting." - read -r -p "Set fallback DNS (1.1.1.1/8.8.8.8)? [y/N]: " choice - case "$choice" in - [yY]*) - pct set "$CTID" --nameserver 1.1.1.1 - pct set "$CTID" --nameserver 8.8.8.8 - if pct exec "$CTID" -- ping -c1 -W1 "$PING_TARGET" >/dev/null 2>&1; then - msg_ok "Network reachable after DNS fallback" - else - msg_error "Still no network/DNS in LXC! Aborting customization." - exit 1 - fi - ;; - *) - msg_error "Aborted by user – no DNS fallback set." - exit 1 - ;; - esac + msg_error "Still no network/DNS in LXC! Aborting customization." + exit 1 fi - done + ;; + *) + msg_error "Aborted by user – no DNS fallback set." + exit 1 + ;; + esac + fi + done - msg_info "Customizing LXC Container" - if [ "$var_os" == "alpine" ]; then - sleep 3 - pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories + msg_info "Customizing LXC Container" + if [ "$var_os" == "alpine" ]; then + sleep 3 + pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories http://dl-cdn.alpinelinux.org/alpine/latest-stable/main http://dl-cdn.alpinelinux.org/alpine/latest-stable/community EOF' - pct exec "$CTID" -- ash -c "apk add bash newt curl openssh nano mc ncurses >/dev/null" - else - sleep 3 + pct exec "$CTID" -- ash -c "apk add bash newt curl openssh nano mc ncurses >/dev/null" + else + sleep 3 - pct exec "$CTID" -- bash -c "sed -i '/$LANG/ s/^# //' /etc/locale.gen" - pct exec "$CTID" -- bash -c "locale_line=\$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print \$1}' | head -n 1) && \ + pct exec "$CTID" -- bash -c "sed -i '/$LANG/ s/^# //' /etc/locale.gen" + pct exec "$CTID" -- bash -c "locale_line=\$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print \$1}' | head -n 1) && \ echo LANG=\$locale_line >/etc/default/locale && \ locale-gen >/dev/null && \ export LANG=\$locale_line" - if [[ -z "${tz:-}" ]]; then - tz=$(timedatectl show --property=Timezone --value 2>/dev/null || echo "Etc/UTC") - fi - - if pct exec "$CTID" -- test -e "/usr/share/zoneinfo/$tz"; then - pct exec "$CTID" -- bash -c "tz='$tz'; echo \"\$tz\" >/etc/timezone && ln -sf \"/usr/share/zoneinfo/\$tz\" /etc/localtime" - else - msg_warn "Skipping timezone setup – zone '$tz' not found in container" - fi - - pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" || { - msg_error "apt-get base packages installation failed" - exit 1 - } + if [[ -z "${tz:-}" ]]; then + tz=$(timedatectl show --property=Timezone --value 2>/dev/null || echo "Etc/UTC") fi - msg_ok "Customized LXC Container" - if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/"$var_install".sh)"; then - return + if pct exec "$CTID" -- test -e "/usr/share/zoneinfo/$tz"; then + pct exec "$CTID" -- bash -c "tz='$tz'; echo \"\$tz\" >/etc/timezone && ln -sf \"/usr/share/zoneinfo/\$tz\" /etc/localtime" + else + msg_warn "Skipping timezone setup – zone '$tz' not found in container" fi + + pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null" || { + msg_error "apt-get base packages installation failed" + exit 1 + } + fi + msg_ok "Customized LXC Container" + + if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/"$var_install".sh)"; then + return + fi } # This function sets the description of the container. description() { - IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) + IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - # Generate LXC Description - DESCRIPTION=$( - cat < Logo @@ -1464,41 +1464,41 @@ description() { EOF - ) + ) - # Set Description in LXC - pct set "$CTID" -description "$DESCRIPTION" + # Set Description in LXC + pct set "$CTID" -description "$DESCRIPTION" - if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service - fi + if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service + fi - post_update_to_api "done" "none" + post_update_to_api "done" "none" } api_exit_script() { - exit_code=$? - if [ $exit_code -ne 0 ]; then - case $exit_code in - 100) post_update_to_api "failed" "100: Unexpected error in create_lxc.sh" ;; - 101) post_update_to_api "failed" "101: No network connection detected in create_lxc.sh" ;; - 200) post_update_to_api "failed" "200: LXC creation failed in create_lxc.sh" ;; - 201) post_update_to_api "failed" "201: Invalid Storage class in create_lxc.sh" ;; - 202) post_update_to_api "failed" "202: User aborted menu in create_lxc.sh" ;; - 203) post_update_to_api "failed" "203: CTID not set in create_lxc.sh" ;; - 204) post_update_to_api "failed" "204: PCT_OSTYPE not set in create_lxc.sh" ;; - 205) post_update_to_api "failed" "205: CTID cannot be less than 100 in create_lxc.sh" ;; - 206) post_update_to_api "failed" "206: CTID already in use in create_lxc.sh" ;; - 207) post_update_to_api "failed" "207: Template not found in create_lxc.sh" ;; - 208) post_update_to_api "failed" "208: Error downloading template in create_lxc.sh" ;; - 209) post_update_to_api "failed" "209: Container creation failed, but template is intact in create_lxc.sh" ;; - *) post_update_to_api "failed" "Unknown error, exit code: $exit_code in create_lxc.sh" ;; - esac - fi + exit_code=$? + if [ $exit_code -ne 0 ]; then + case $exit_code in + 100) post_update_to_api "failed" "100: Unexpected error in create_lxc.sh" ;; + 101) post_update_to_api "failed" "101: No network connection detected in create_lxc.sh" ;; + 200) post_update_to_api "failed" "200: LXC creation failed in create_lxc.sh" ;; + 201) post_update_to_api "failed" "201: Invalid Storage class in create_lxc.sh" ;; + 202) post_update_to_api "failed" "202: User aborted menu in create_lxc.sh" ;; + 203) post_update_to_api "failed" "203: CTID not set in create_lxc.sh" ;; + 204) post_update_to_api "failed" "204: PCT_OSTYPE not set in create_lxc.sh" ;; + 205) post_update_to_api "failed" "205: CTID cannot be less than 100 in create_lxc.sh" ;; + 206) post_update_to_api "failed" "206: CTID already in use in create_lxc.sh" ;; + 207) post_update_to_api "failed" "207: Template not found in create_lxc.sh" ;; + 208) post_update_to_api "failed" "208: Error downloading template in create_lxc.sh" ;; + 209) post_update_to_api "failed" "209: Container creation failed, but template is intact in create_lxc.sh" ;; + *) post_update_to_api "failed" "Unknown error, exit code: $exit_code in create_lxc.sh" ;; + esac + fi } if command -v pveversion >/dev/null 2>&1; then - trap 'api_exit_script' EXIT + trap 'api_exit_script' EXIT fi trap 'post_update_to_api "failed" "$BASH_COMMAND"' ERR trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT From c683060454da77d1efdcb4229537719f8dd99927 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 10:43:26 +0200 Subject: [PATCH 446/463] Update build.func --- misc/build.func | 66 +++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/misc/build.func b/misc/build.func index 80265458..4d8e759a 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1354,42 +1354,38 @@ EOF fi done - if [ "$var_os" == "alpine" ]; then - PING_TARGET="1.1.1.1" - else - PING_TARGET="deb.debian.org" - fi - - msg_info "Waiting for network in LXC container" - for i in {1..10}; do - if pct exec "$CTID" -- ping -c1 -W1 "$PING_TARGET" >/dev/null 2>&1; then - msg_ok "Network in LXC is reachable" - break - fi - if [ "$i" -lt 10 ]; then - msg_warn "No network yet in LXC (try $i/10) – waiting..." - sleep 3 - else - msg_error "No network in LXC after waiting." - read -r -p "Set fallback DNS (1.1.1.1/8.8.8.8)? [y/N]: " choice - case "$choice" in - [yY]*) - pct set "$CTID" --nameserver 1.1.1.1 - pct set "$CTID" --nameserver 8.8.8.8 - if pct exec "$CTID" -- ping -c1 -W1 "$PING_TARGET" >/dev/null 2>&1; then - msg_ok "Network reachable after DNS fallback" - else - msg_error "Still no network/DNS in LXC! Aborting customization." + if [ "$var_os" != "alpine" ]; then + msg_info "Waiting for network in LXC container" + for i in {1..10}; do + if pct exec "$CTID" -- ping -c1 -W1 deb.debian.org >/dev/null 2>&1; then + msg_ok "Network in LXC is reachable" + break + fi + if [ "$i" -lt 10 ]; then + msg_warn "No network yet in LXC (try $i/10) – waiting..." + sleep 3 + else + msg_error "No network in LXC after waiting." + read -r -p "Set fallback DNS (1.1.1.1/8.8.8.8)? [y/N]: " choice + case "$choice" in + [yY]*) + pct set "$CTID" --nameserver 1.1.1.1 + pct set "$CTID" --nameserver 8.8.8.8 + if pct exec "$CTID" -- ping -c1 -W1 deb.debian.org >/dev/null 2>&1; then + msg_ok "Network reachable after DNS fallback" + else + msg_error "Still no network/DNS in LXC! Aborting customization." + exit 1 + fi + ;; + *) + msg_error "Aborted by user – no DNS fallback set." exit 1 - fi - ;; - *) - msg_error "Aborted by user – no DNS fallback set." - exit 1 - ;; - esac - fi - done + ;; + esac + fi + done + fi msg_info "Customizing LXC Container" if [ "$var_os" == "alpine" ]; then From 2db04e501d349761f29f8afa4d18ccc897590ba7 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 10:43:56 +0200 Subject: [PATCH 447/463] Update linkstack-install.sh --- install/linkstack-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/linkstack-install.sh b/install/linkstack-install.sh index 81fb19bb..95105bbf 100644 --- a/install/linkstack-install.sh +++ b/install/linkstack-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -PHP_VERSION="8.3" PHP_MODULE="sqlite3,mysql" PHP_APACHE="YES" setup_php +PHP_VERSION="8.3" PHP_MODULE="sqlite3" PHP_APACHE="YES" setup_php fetch_and_deploy_gh_release "linkstack" "linkstackorg/linkstack" "prebuild" "latest" "/var/www/html/linkstack" "linkstack.zip" msg_info "Configuring LinkStack" From 4c35a783ad58f624c2b8279cef96042e97a347e0 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 10:48:56 +0200 Subject: [PATCH 448/463] test --- install/linkstack-install.sh | 2 +- misc/tools.func | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/install/linkstack-install.sh b/install/linkstack-install.sh index 95105bbf..81fb19bb 100644 --- a/install/linkstack-install.sh +++ b/install/linkstack-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -PHP_VERSION="8.3" PHP_MODULE="sqlite3" PHP_APACHE="YES" setup_php +PHP_VERSION="8.3" PHP_MODULE="sqlite3,mysql" PHP_APACHE="YES" setup_php fetch_and_deploy_gh_release "linkstack" "linkstackorg/linkstack" "prebuild" "latest" "/var/www/html/linkstack" "linkstack.zip" msg_info "Configuring LinkStack" diff --git a/misc/tools.func b/misc/tools.func index 89d17102..54773b30 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -460,7 +460,7 @@ function setup_php() { MODULE_LIST+=" php${PHP_VERSION}-fpm" fi if [[ "$PHP_APACHE" == "YES" ]]; then - $STD apt-get install -y apache2 + $STD apt-get install -y apache2 libapache2-mod-php${PHP_VERSION} $STD systemctl restart apache2 || true fi From 96351e0441c979718f76e51cac73f8559c229014 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 10:52:35 +0200 Subject: [PATCH 449/463] Update teamspeak-server-install.sh --- install/teamspeak-server-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/teamspeak-server-install.sh b/install/teamspeak-server-install.sh index 8fb45f2c..cee27f4a 100644 --- a/install/teamspeak-server-install.sh +++ b/install/teamspeak-server-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | grep -oP 'teamspeak3-server_linux_amd64-\K[0-9]+\.[0-9]+\.[0-9]+' | head -1) +RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | grep -Eo 'teamspeak3-server_linux_amd64-[0-9]+\.[0-9]+\.[0-9]+' | head -n1 | sed 's/teamspeak3-server_linux_amd64-//') msg_info "Setting up Teamspeak Server" curl -fsSL "https://files.teamspeak-services.com/releases/server/${RELEASE}/teamspeak3-server_linux_amd64-${RELEASE}.tar.bz2" -o ts3server.tar.bz2 From 9c92bced1108793e5eed078a55450995178e0aad Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 10:57:21 +0200 Subject: [PATCH 450/463] Update tools.func --- misc/tools.func | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 54773b30..df5934cc 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -465,8 +465,10 @@ function setup_php() { fi if [[ "$PHP_APACHE" == "YES" ]] && [[ -n "$CURRENT_PHP" ]]; then - if [[ -f /etc/apache2/mods-enabled/php${CURRENT_PHP}.load ]]; then - $STD a2dismod php"${CURRENT_PHP}" || true + if [[ "$CURRENT_PHP" != "$PHP_VERSION" ]]; then + if [[ -f /etc/apache2/mods-enabled/php${CURRENT_PHP}.load ]]; then + $STD a2dismod php"${CURRENT_PHP}" || true + fi fi fi From 03dcdfb2fbd777dbad08846fa0a478ffb5068b44 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 11:05:24 +0200 Subject: [PATCH 451/463] Update build.func --- misc/build.func | 174 ++++++++++++++++++++++++++---------------------- 1 file changed, 95 insertions(+), 79 deletions(-) diff --git a/misc/build.func b/misc/build.func index 4d8e759a..61ba50dc 100644 --- a/misc/build.func +++ b/misc/build.func @@ -998,95 +998,111 @@ install_script() { if systemctl is-active -q ping-instances.service; then systemctl -q stop ping-instances.service fi + NEXTID=$(pvesh get /cluster/nextid) timezone=$(cat /etc/timezone) header_info - while true; do - TMP_CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ - --title "SETTINGS" \ - --menu "Choose an option:" 20 60 7 \ - "1" "Default Settings" \ - "2" "Default Settings (with verbose)" \ - "3" "Advanced Settings" \ - "4" "Use Config File" \ - "5" "Manage Default Storage" \ - "6" "Diagnostic Settings" \ - "7" "Exit" \ - --default-item "1" 3>&1 1>&2 2>&3) || true - - if [ -z "$TMP_CHOICE" ]; then - echo -e "\n${CROSS}${RD}Menu canceled. Exiting script.${CL}\n" - exit 0 - fi - - CHOICE="$TMP_CHOICE" - - case $CHOICE in - 1) - header_info - echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME${CL}" - VERBOSE="no" - METHOD="default" - base_settings "$VERBOSE" - echo_default - break + # --- PRESET support --- + if [ -n "${PRESET:-}" ]; then + case "$PRESET" in + DEFAULT | default | 1) + CHOICE="1" ;; - 2) - header_info - echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME (${VERBOSE_CROPPED}Verbose)${CL}" - VERBOSE="yes" - METHOD="default" - base_settings "$VERBOSE" - echo_default - break + VERBOSE | verbose | 2) + CHOICE="2" ;; - 3) - header_info - echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" - METHOD="advanced" - base_settings - advanced_settings - break - ;; - 4) - header_info - echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" - METHOD="advanced" - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/config-file.func) - config_file - break - ;; - - 5) - manage_default_storage - ;; - 6) - if [[ $DIAGNOSTICS == "yes" ]]; then - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ - --yes-button "No" --no-button "Back"; then - DIAGNOSTICS="no" - sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 - fi - else - if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ - --yes-button "Yes" --no-button "Back"; then - DIAGNOSTICS="yes" - sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics - whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 - fi - fi - ;; - 7) - echo -e "\n${CROSS}${RD}Script terminated. Have a great day!${CL}\n" - exit 0 + ADVANCED | advanced | 3) + CHOICE="3" ;; *) - echo -e "${CROSS}${RD}Invalid option, please try again.${CL}" + echo -e "\n${CROSS}${RD}Invalid PRESET value: ${PRESET}${CL}\n" + exit 1 ;; esac - done + else + while true; do + TMP_CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \ + --title "SETTINGS" \ + --menu "Choose an option:" 20 60 7 \ + "1" "Default Settings" \ + "2" "Default Settings (with verbose)" \ + "3" "Advanced Settings" \ + "4" "Use Config File" \ + "5" "Manage Default Storage" \ + "6" "Diagnostic Settings" \ + "7" "Exit" \ + --default-item "1" 3>&1 1>&2 2>&3) || true + + if [ -z "$TMP_CHOICE" ]; then + echo -e "\n${CROSS}${RD}Menu canceled. Exiting script.${CL}\n" + exit 0 + fi + + CHOICE="$TMP_CHOICE" + break + done + fi + + case $CHOICE in + 1) + header_info + echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME${CL}" + VERBOSE="no" + METHOD="default" + base_settings "$VERBOSE" + echo_default + ;; + 2) + header_info + echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings on node $PVEHOST_NAME (${VERBOSE_CROPPED}Verbose)${CL}" + VERBOSE="yes" + METHOD="default" + base_settings "$VERBOSE" + echo_default + ;; + 3) + header_info + echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings on node $PVEHOST_NAME${CL}" + METHOD="advanced" + base_settings + advanced_settings + ;; + 4) + header_info + echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" + METHOD="advanced" + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/config-file.func) + config_file + ;; + 5) + manage_default_storage + ;; + 6) + if [[ $DIAGNOSTICS == "yes" ]]; then + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ + --yes-button "No" --no-button "Back"; then + DIAGNOSTICS="no" + sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 + fi + else + if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \ + --yes-button "Yes" --no-button "Back"; then + DIAGNOSTICS="yes" + sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics + whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58 + fi + fi + ;; + 7) + echo -e "\n${CROSS}${RD}Script terminated. Have a great day!${CL}\n" + exit 0 + ;; + *) + echo -e "${CROSS}${RD}Invalid option, please try again.${CL}" + ;; + esac } check_container_resources() { From 2000987e247e20980cfbb917f904b9604272c15f Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 11:21:35 +0200 Subject: [PATCH 452/463] Update tools.func --- misc/tools.func | 64 +++++++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index df5934cc..6d932e03 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -416,9 +416,10 @@ function setup_php() { COMBINED_MODULES="${DEFAULT_MODULES}" fi - # Deduplicate modules + # Deduplicate COMBINED_MODULES=$(echo "$COMBINED_MODULES" | tr ',' '\n' | awk '!seen[$0]++' | paste -sd, -) + # Aktuelle PHP-CLI-Version ermitteln local CURRENT_PHP="" if command -v php >/dev/null 2>&1; then CURRENT_PHP=$(php -v 2>/dev/null | awk '/^PHP/{print $2}' | cut -d. -f1,2) @@ -440,13 +441,8 @@ function setup_php() { $STD apt-get update fi + # Modul-Liste bauen local MODULE_LIST="php${PHP_VERSION}" - for pkg in $MODULE_LIST; do - if ! apt-cache show "$pkg" >/dev/null 2>&1; then - msg_error "Package not found: $pkg" - exit 1 - fi - done IFS=',' read -ra MODULES <<<"$COMBINED_MODULES" for mod in "${MODULES[@]}"; do if apt-cache show "php${PHP_VERSION}-${mod}" >/dev/null 2>&1; then @@ -455,51 +451,34 @@ function setup_php() { msg_warn "PHP-Module ${mod} for PHP ${PHP_VERSION} not found – skipping" fi done - if [[ "$PHP_FPM" == "YES" ]]; then MODULE_LIST+=" php${PHP_VERSION}-fpm" fi - if [[ "$PHP_APACHE" == "YES" ]]; then - $STD apt-get install -y apache2 libapache2-mod-php${PHP_VERSION} - $STD systemctl restart apache2 || true - fi - if [[ "$PHP_APACHE" == "YES" ]] && [[ -n "$CURRENT_PHP" ]]; then - if [[ "$CURRENT_PHP" != "$PHP_VERSION" ]]; then - if [[ -f /etc/apache2/mods-enabled/php${CURRENT_PHP}.load ]]; then - $STD a2dismod php"${CURRENT_PHP}" || true - fi + # Apache + PHP-Modul nur installieren, wenn noch nicht vorhanden + if [[ "$PHP_APACHE" == "YES" ]]; then + if ! dpkg -l | grep -q "libapache2-mod-php${PHP_VERSION}"; then + msg_info "Installing Apache with PHP${PHP_VERSION} support" + $STD apt-get install -y apache2 libapache2-mod-php${PHP_VERSION} + else + msg_info "Apache with PHP${PHP_VERSION} already installed – skipping install" fi fi - if [[ "$PHP_FPM" == "YES" ]] && [[ -n "$CURRENT_PHP" ]]; then + # setup / update PHP modules + $STD apt-get install -y $MODULE_LIST + msg_ok "Setup PHP $PHP_VERSION" + + # optional stop old PHP-FPM service + if [[ "$PHP_FPM" == "YES" && -n "$CURRENT_PHP" && "$CURRENT_PHP" != "$PHP_VERSION" ]]; then $STD systemctl stop php"${CURRENT_PHP}"-fpm || true $STD systemctl disable php"${CURRENT_PHP}"-fpm || true fi - if [[ "$PHP_APACHE" == "YES" ]]; then - if [[ -f /etc/apache2/mods-enabled/php${PHP_VERSION}.load ]]; then - $STD a2enmod php"${PHP_VERSION}" - else - $STD a2enmod php"${PHP_VERSION}" - fi - $STD systemctl restart apache2 || true - fi - - if [[ "$PHP_FPM" == "YES" ]]; then - if systemctl list-unit-files | grep -q "php${PHP_VERSION}-fpm.service"; then - $STD systemctl enable php${PHP_VERSION}-fpm - $STD systemctl restart php${PHP_VERSION}-fpm - else - msg_warn "FPM requested but service php${PHP_VERSION}-fpm not found" - fi - fi - # Patch all relevant php.ini files local PHP_INI_PATHS=("/etc/php/${PHP_VERSION}/cli/php.ini") [[ "$PHP_FPM" == "YES" ]] && PHP_INI_PATHS+=("/etc/php/${PHP_VERSION}/fpm/php.ini") [[ "$PHP_APACHE" == "YES" ]] && PHP_INI_PATHS+=("/etc/php/${PHP_VERSION}/apache2/php.ini") - for ini in "${PHP_INI_PATHS[@]}"; do if [[ -f "$ini" ]]; then $STD msg_info "Patching $ini" @@ -518,9 +497,20 @@ function setup_php() { $STD a2dismod "$mod" || true fi done + $STD a2enmod mpm_prefork $STD a2enmod "php${PHP_VERSION}" $STD systemctl restart apache2 || true fi + + # FPM aktivieren, falls gewünscht + if [[ "$PHP_FPM" == "YES" ]]; then + if systemctl list-unit-files | grep -q "php${PHP_VERSION}-fpm.service"; then + $STD systemctl enable php${PHP_VERSION}-fpm + $STD systemctl restart php${PHP_VERSION}-fpm + else + msg_warn "FPM requested but service php${PHP_VERSION}-fpm not found" + fi + fi } # ------------------------------------------------------------------------------ From b93f8ce5febca0eb816349f442d02564703095a2 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 11:56:25 +0200 Subject: [PATCH 453/463] logging --- misc/build.func | 2 +- misc/tools.func | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/misc/build.func b/misc/build.func index 61ba50dc..e9247b9d 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1438,7 +1438,7 @@ EOF' msg_ok "Customized LXC Container" if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/"$var_install".sh)"; then - return + exit $? fi } diff --git a/misc/tools.func b/misc/tools.func index 6d932e03..dace8ca7 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -419,7 +419,7 @@ function setup_php() { # Deduplicate COMBINED_MODULES=$(echo "$COMBINED_MODULES" | tr ',' '\n' | awk '!seen[$0]++' | paste -sd, -) - # Aktuelle PHP-CLI-Version ermitteln + # Get current PHP-CLI version local CURRENT_PHP="" if command -v php >/dev/null 2>&1; then CURRENT_PHP=$(php -v 2>/dev/null | awk '/^PHP/{print $2}' | cut -d. -f1,2) @@ -441,7 +441,7 @@ function setup_php() { $STD apt-get update fi - # Modul-Liste bauen + # Build module list local MODULE_LIST="php${PHP_VERSION}" IFS=',' read -ra MODULES <<<"$COMBINED_MODULES" for mod in "${MODULES[@]}"; do @@ -455,7 +455,7 @@ function setup_php() { MODULE_LIST+=" php${PHP_VERSION}-fpm" fi - # Apache + PHP-Modul nur installieren, wenn noch nicht vorhanden + # install apache2 with PHP support if requested if [[ "$PHP_APACHE" == "YES" ]]; then if ! dpkg -l | grep -q "libapache2-mod-php${PHP_VERSION}"; then msg_info "Installing Apache with PHP${PHP_VERSION} support" @@ -502,7 +502,7 @@ function setup_php() { $STD systemctl restart apache2 || true fi - # FPM aktivieren, falls gewünscht + # enable and restart PHP-FPM if requested if [[ "$PHP_FPM" == "YES" ]]; then if systemctl list-unit-files | grep -q "php${PHP_VERSION}-fpm.service"; then $STD systemctl enable php${PHP_VERSION}-fpm From cd1b676097f20a0d7408661646ef7d9af7fb4847 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 11:56:49 +0200 Subject: [PATCH 454/463] Update linkstack-install.sh --- install/linkstack-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/linkstack-install.sh b/install/linkstack-install.sh index 81fb19bb..8801b2c3 100644 --- a/install/linkstack-install.sh +++ b/install/linkstack-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -PHP_VERSION="8.3" PHP_MODULE="sqlite3,mysql" PHP_APACHE="YES" setup_php +PHP_VERSION="8.3" PHP_MODULE="sqlite3,mysql,ronny" PHP_APACHE="YES" setup_php fetch_and_deploy_gh_release "linkstack" "linkstackorg/linkstack" "prebuild" "latest" "/var/www/html/linkstack" "linkstack.zip" msg_info "Configuring LinkStack" From 277d94584c15a605a522876452f3324d183b50dc Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 12:16:35 +0200 Subject: [PATCH 455/463] Update maxun-install.sh --- install/maxun-install.sh | 94 ++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/install/maxun-install.sh b/install/maxun-install.sh index f68515a1..57239c76 100644 --- a/install/maxun-install.sh +++ b/install/maxun-install.sh @@ -15,35 +15,32 @@ update_os msg_info "Installing Dependencies" $STD apt-get install -y \ - gpg \ - openssl \ - redis \ - libgbm1 \ - libnss3 \ - libatk1.0-0 \ - libatk-bridge2.0-0 \ - libdrm2 \ - libxkbcommon0 \ - libglib2.0-0 \ - libdbus-1-3 \ - libx11-xcb1 \ - libxcb1 \ - libxcomposite1 \ - libxcursor1 \ - libxdamage1 \ - libxext6 \ - libxi6 \ - libxtst6 \ - ca-certificates \ - libxrandr2 \ - libasound2 \ - libxss1 \ - libxinerama1 \ - nginx + openssl \ + redis \ + libgbm1 \ + libnss3 \ + libatk1.0-0 \ + libatk-bridge2.0-0 \ + libdrm2 \ + libxkbcommon0 \ + libglib2.0-0 \ + libdbus-1-3 \ + libx11-xcb1 \ + libxcb1 \ + libxcomposite1 \ + libxcursor1 \ + libxdamage1 \ + libxext6 \ + libxi6 \ + libxtst6 \ + ca-certificates \ + libxrandr2 \ + libasound2 \ + libxss1 \ + libxinerama1 \ + nginx msg_ok "Installed Dependencies" -#configure_lxc "Semantic Search requires a dedicated GPU and at least 16GB RAM. Would you like to install it?" 100 "memory" "16000" - PG_VERSION=17 setup_postgresql NODE_VERSION="22" setup_nodejs @@ -56,6 +53,7 @@ MINIO_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13) JWT_SECRET=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32) ENCRYPTION_KEY=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32) LOCAL_IP=$(hostname -I | awk '{print $1}') +SESSION_SECRET=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32) msg_ok "Set up Variables" msg_info "Setup Database" @@ -65,12 +63,13 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8' $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'" { - echo "Maxun-Credentials" - echo "Maxun Database User: $DB_USER" - echo "Maxun Database Password: $DB_PASS" - echo "Maxun Database Name: $DB_NAME" - echo "Maxun JWT Secret: $JWT_SECRET" - echo "Maxun Encryption Key: $ENCRYPTION_KEY" + echo "Maxun-Credentials" + echo "Maxun Database User: $DB_USER" + echo "Maxun Database Password: $DB_PASS" + echo "Maxun Database Name: $DB_NAME" + echo "Maxun JWT Secret: $JWT_SECRET" + echo "Maxun Encryption Key: $ENCRYPTION_KEY" + echo "Maxun Session Secret: $SESSION_SECRET" } >>~/maxun.creds msg_ok "Set up Database" @@ -99,9 +98,9 @@ LimitNOFILE=65536 WantedBy=multi-user.target EOF { - echo "__________________" - echo "MinIO Admin User: $MINIO_USER" - echo "MinIO Admin Password: $MINIO_PASS" + echo "__________________" + echo "MinIO Admin User: $MINIO_USER" + echo "MinIO Admin Password: $MINIO_PASS" } >>~/maxun.creds cat </etc/default/minio MINIO_ROOT_USER=${MINIO_USER} @@ -110,8 +109,9 @@ EOF systemctl enable -q --now minio msg_ok "Setup MinIO" -msg_info "Installing Maxun (Patience)" fetch_and_deploy_gh_release "maxun" "getmaxun/maxun" "source" + +msg_info "Installing Maxun (Patience)" cat </opt/maxun/.env NODE_ENV=development JWT_SECRET=${JWT_SECRET} @@ -137,6 +137,7 @@ VITE_BACKEND_URL=http://${LOCAL_IP}:8080 VITE_PUBLIC_URL=http://${LOCAL_IP}:5173 MAXUN_TELEMETRY=false +SESSION_SECRET=${SESSION_SECRET} EOF cat <<'EOF' >/usr/local/bin/update-env-ip.sh @@ -162,19 +163,27 @@ msg_info "Setting up nginx with CORS Proxy" cat <<'EOF' >/etc/nginx/sites-available/maxun server { listen 80; + server_name _; + # Frontend ausliefern + root /usr/share/nginx/html; + index index.html; location / { - root /usr/share/nginx/html; try_files $uri $uri/ /index.html; } - location ~ ^/(api|record|workflow|storage|auth|integration|proxy|api-docs) { - proxy_pass http://localhost:8080; - proxy_set_header Host $host; + # Backend Proxy + location ~ ^/(auth|storage|record|workflow|robot|proxy|api-docs|api|webhook)(/|$) { + proxy_pass http://127.0.0.1:8080; + proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; - proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + # CORS add_header Access-Control-Allow-Origin "$http_origin" always; add_header Access-Control-Allow-Credentials true always; add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS always; @@ -193,7 +202,6 @@ server { } } EOF - ln -sf /etc/nginx/sites-available/maxun /etc/nginx/sites-enabled/maxun rm -f /etc/nginx/sites-enabled/default msg_ok "nginx with CORS Proxy set up" From bd3fb793b76304212145e3bbc5bec65f5f64d34b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 12:21:12 +0200 Subject: [PATCH 456/463] Update create_lxc.sh --- misc/create_lxc.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index d74ee9fa..fe4fa8ec 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -110,6 +110,19 @@ function select_storage() { ;; esac + # >>> NEW: support STORAGE preset <<< + if [ -n "${STORAGE:-}" ]; then + # validate the given storage + if pvesm status -content "$CONTENT" | awk 'NR>1 {print $1}' | grep -qx "$STORAGE"; then + STORAGE_RESULT="$STORAGE" + msg_info "Using preset storage: $STORAGE_RESULT for $CONTENT_LABEL" + return 0 + else + msg_error "Preset storage '$STORAGE' is not valid for content type '$CONTENT'." + return 2 + fi + fi + local -a MENU local -A STORAGE_MAP local COL_WIDTH=0 From 58695de2e09778d1bcd2c4e7587632569ac34cab Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 12:21:41 +0200 Subject: [PATCH 457/463] Update maxun-install.sh --- install/maxun-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/maxun-install.sh b/install/maxun-install.sh index 57239c76..e0caea03 100644 --- a/install/maxun-install.sh +++ b/install/maxun-install.sh @@ -42,7 +42,7 @@ $STD apt-get install -y \ msg_ok "Installed Dependencies" PG_VERSION=17 setup_postgresql -NODE_VERSION="22" setup_nodejs +NODE_VERSION="18" setup_nodejs msg_info "Setup Variables" DB_NAME=maxun_db From e33b0a93b18f5412d4286b05d570a0c003291306 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 12:23:37 +0200 Subject: [PATCH 458/463] Update create_lxc.sh --- misc/create_lxc.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh index fe4fa8ec..b7d1f46e 100644 --- a/misc/create_lxc.sh +++ b/misc/create_lxc.sh @@ -111,8 +111,7 @@ function select_storage() { esac # >>> NEW: support STORAGE preset <<< - if [ -n "${STORAGE:-}" ]; then - # validate the given storage + if [ "$CONTENT" = "rootdir" ] && [ -n "${STORAGE:-}" ]; then if pvesm status -content "$CONTENT" | awk 'NR>1 {print $1}' | grep -qx "$STORAGE"; then STORAGE_RESULT="$STORAGE" msg_info "Using preset storage: $STORAGE_RESULT for $CONTENT_LABEL" @@ -122,7 +121,6 @@ function select_storage() { return 2 fi fi - local -a MENU local -A STORAGE_MAP local COL_WIDTH=0 From 97c13e8b7ced5442c2f999e724593166f8059af9 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 12:29:34 +0200 Subject: [PATCH 459/463] Update leantime-install.sh --- install/leantime-install.sh | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/install/leantime-install.sh b/install/leantime-install.sh index cd577289..026bc2cb 100644 --- a/install/leantime-install.sh +++ b/install/leantime-install.sh @@ -13,29 +13,10 @@ setting_up_container network_check update_os -PHP_VERSION=8.4 -PHP_MODULE=mysql -PHP_APACHE=YES -PHP_FPM=YES - -msg_info "Installing Apache2" -$STD apt-get install -y \ - apache2 -msg_ok "Installed Apache2" - -setup_php - -msg_info "Installing Apache2 mod for PHP" -$STD apt-get install -y \ - "libapache2-mod-php${PHP_VERSION}" -msg_ok "Installed Apache2 mod" - +PHP_VERSION=8.4 PHP_MODULE="mysql" PHP_APACHE="YES" PHP_FPM="YES" setup_php setup_mariadb -msg_ok "Installed Dependencies" - msg_info "Setting up Database" -systemctl enable -q --now mariadb DB_NAME=leantime DB_USER=leantime DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) @@ -50,9 +31,10 @@ $STD mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH } >>~/"$APPLICATION".creds msg_ok "Set up Database" +fetch_and_deploy_gh_release "leantime" "Leantime/leantime" "prebuild" "latest" "/opt/leantime" Leantime*.tar.gz + msg_info "Setup ${APPLICATION}" APACHE_LOG_DIR=/var/log/apache2 -fetch_and_deploy_gh_release "$APPLICATION" "Leantime/leantime" "prebuild" "latest" "/opt/${APPLICATION}" Leantime-v[0-9].[0-9].[0-9].tar.gz chown -R www-data:www-data "/opt/${APPLICATION}" chmod -R 750 "/opt/${APPLICATION}" From 5c147d9841fa0bbbc80fda7b5f19411c9f52821a Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 12:57:59 +0200 Subject: [PATCH 460/463] Update leantime-install.sh --- install/leantime-install.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/install/leantime-install.sh b/install/leantime-install.sh index 026bc2cb..ff358010 100644 --- a/install/leantime-install.sh +++ b/install/leantime-install.sh @@ -35,17 +35,17 @@ fetch_and_deploy_gh_release "leantime" "Leantime/leantime" "prebuild" "latest" " msg_info "Setup ${APPLICATION}" APACHE_LOG_DIR=/var/log/apache2 -chown -R www-data:www-data "/opt/${APPLICATION}" -chmod -R 750 "/opt/${APPLICATION}" +chown -R www-data:www-data "/opt/leantime" +chmod -R 750 "/opt/leantime" cat </etc/apache2/sites-enabled/000-default.conf ServerAdmin webmaster@localhost - DocumentRoot /opt/${APPLICATION}/public + DocumentRoot /opt/leantime/public DirectoryIndex index.php index.html index.cgi index.pl index.xhtml Options +ExecCGI - + Options FollowSymLinks Require all granted AllowOverride All @@ -60,12 +60,12 @@ cat </etc/apache2/sites-enabled/000-default.conf EOF -mv "/opt/${APPLICATION}/config/sample.env" "/opt/${APPLICATION}/config/.env" +mv "/opt/leantime/config/sample.env" "/opt/leantime/config/.env" sed -i -e "s|^LEAN_DB_DATABASE.*|LEAN_DB_DATABASE = '$DB_NAME'|" \ -e "s|^LEAN_DB_USER.*|LEAN_DB_USER = '$DB_USER'|" \ -e "s|^LEAN_DB_PASSWORD.*|LEAN_DB_PASSWORD = '$DB_PASS'|" \ -e "s|^LEAN_SESSION_PASSWORD.*|LEAN_SESSION_PASSWORD = '$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)'|" \ - "/opt/${APPLICATION}/config/.env" + "/opt/leantime/config/.env" a2enmod -q proxy_fcgi setenvif rewrite a2enconf -q "php${PHP_VERSION}-fpm" From a4a8fab2fa7480a875f9455f4df48f13f603fe90 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Jul 2025 12:02:57 +0000 Subject: [PATCH 461/463] Bump form-data in /frontend in the npm_and_yarn group across 1 directory Bumps the npm_and_yarn group with 1 update in the /frontend directory: [form-data](https://github.com/form-data/form-data). Updates `form-data` from 4.0.1 to 4.0.4 - [Release notes](https://github.com/form-data/form-data/releases) - [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md) - [Commits](https://github.com/form-data/form-data/compare/v4.0.1...v4.0.4) --- updated-dependencies: - dependency-name: form-data dependency-version: 4.0.4 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] --- frontend/package-lock.json | 120 +++++++++++++++++++++++++++---------- 1 file changed, 89 insertions(+), 31 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 9c8b7c97..fe7ecb63 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -4082,6 +4082,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -4694,6 +4708,21 @@ "dev": true, "license": "MIT" }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -4804,14 +4833,11 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -4860,9 +4886,9 @@ "license": "MIT" }, "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, "license": "MIT", "dependencies": { @@ -4873,15 +4899,16 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -5728,14 +5755,16 @@ } }, "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -5851,17 +5880,22 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -5879,6 +5913,20 @@ "node": ">=6" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", @@ -5982,13 +6030,13 @@ "license": "MIT" }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6055,9 +6103,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", "engines": { @@ -7037,6 +7085,16 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", From 042ef3736536f3bae6b1d00b8966d0e758129ebc Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Tue, 22 Jul 2025 15:59:29 +0200 Subject: [PATCH 462/463] . --- ct/salt.sh | 50 ----------------------- ct/teamspeak-server.sh | 61 ----------------------------- install/salt-install.sh | 44 --------------------- install/teamspeak-server-install.sh | 56 -------------------------- 4 files changed, 211 deletions(-) delete mode 100644 ct/salt.sh delete mode 100644 ct/teamspeak-server.sh delete mode 100644 install/salt-install.sh delete mode 100644 install/teamspeak-server-install.sh diff --git a/ct/salt.sh b/ct/salt.sh deleted file mode 100644 index c8a6cec7..00000000 --- a/ct/salt.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -source <(curl -s https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) -# Copyright (c) 2021-2025 community-scripts ORG -# Author: bvdberg01 -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/saltstack/salt - -APP="Salt" -var_tags="${var_tags:-automations}" -var_cpu="${var_cpu:-1}" -var_ram="${var_ram:-1024}" -var_disk="${var_disk:-3}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -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 /etc/salt ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - - RELEASE=$(curl -fsSL https://api.github.com/repos/saltstack/salt/releases/latest | jq -r .tag_name | sed 's/^v//') - if [[ ! -f /~.salt ]] || [[ "${RELEASE}" != "$(cat /~.salt)" ]]; then - msg_info "Updating $APP to ${RELEASE}" - sed -i "s/^\(Pin: version \).*/\1${RELEASE}/" /etc/apt/preferences.d/salt-pin-1001 - $STD apt-get update - $STD apt-get upgrade -y - echo "${RELEASE}" >/~.salt - msg_ok "Updated ${APP} to ${RELEASE}" - else - msg_ok "${APP} is already up to date (${RELEASE})" - fi -} - -start -build_container -description - -msg_ok "Completed Successfully!\n" -echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" diff --git a/ct/teamspeak-server.sh b/ct/teamspeak-server.sh deleted file mode 100644 index 55f51b85..00000000 --- a/ct/teamspeak-server.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2025 community-scripts ORG -# Author: tremor021 (Slaviša Arežina) -# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE -# Source: https://teamspeak.com/en/ - -APP="Teamspeak-Server" -var_tags="${var_tags:-voice;communication}" -var_cpu="${var_cpu:-1}" -var_ram="${var_ram:-512}" -var_disk="${var_disk:-2}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -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/teamspeak-server ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - - RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | grep -oP 'teamspeak3-server_linux_amd64-\K[0-9]+\.[0-9]+\.[0-9]+' | head -1) - if [[ "${RELEASE}" != "$(cat ~/.teamspeak-server 2>/dev/null)" ]] || [[ ! -f ~/.teamspeak-server ]]; then - msg_info "Stopping Service" - systemctl stop teamspeak-server - msg_ok "Stopped Service" - - msg_info "Updating ${APP}" - curl -fsSL "https://files.teamspeak-services.com/releases/server/${RELEASE}/teamspeak3-server_linux_amd64-${RELEASE}.tar.bz2" -o ts3server.tar.bz2 - tar -xf ./ts3server.tar.bz2 - cp -ru teamspeak3-server_linux_amd64/* /opt/teamspeak-server/ - msg_ok "Updated $APP" - - msg_info "Starting Service" - systemctl start teamspeak-server - msg_ok "Started Service" - - msg_ok "Updated Successfully" - else - msg_ok "Already up to date" - 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}${IP}:9987${CL}" diff --git a/install/salt-install.sh b/install/salt-install.sh deleted file mode 100644 index 4fe29a82..00000000 --- a/install/salt-install.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 community-scripts ORG -# Author: bvdberg01 -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/saltstack/salt - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apt-get install -y jq -msg_ok "Installed Dependencies" - -msg_info "Setup Salt Repo" -mkdir -p /etc/apt/keyrings -curl -fsSL https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public -o /etc/apt/keyrings/salt-archive-keyring.pgp -curl -fsSL https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.sources -o /etc/apt/sources.list.d/salt.sources -$STD apt-get update -msg_ok "Setup Salt Repo" - -msg_info "Installing Salt" -RELEASE=$(curl -fsSL https://api.github.com/repos/saltstack/salt/releases/latest | jq -r .tag_name | sed 's/^v//') -cat </etc/apt/preferences.d/salt-pin-1001 -Package: salt-* -Pin: version ${RELEASE} -Pin-Priority: 1001 -EOF -$STD apt-get install -y salt-master -echo "${RELEASE}" >/~.salt -msg_ok "Installed Salt" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" diff --git a/install/teamspeak-server-install.sh b/install/teamspeak-server-install.sh deleted file mode 100644 index cee27f4a..00000000 --- a/install/teamspeak-server-install.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2025 community-scripts ORG -# Author: tremor021 (Slaviša Arežina) -# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE -# Source: https://teamspeak.com/en/ - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | grep -Eo 'teamspeak3-server_linux_amd64-[0-9]+\.[0-9]+\.[0-9]+' | head -n1 | sed 's/teamspeak3-server_linux_amd64-//') - -msg_info "Setting up Teamspeak Server" -curl -fsSL "https://files.teamspeak-services.com/releases/server/${RELEASE}/teamspeak3-server_linux_amd64-${RELEASE}.tar.bz2" -o ts3server.tar.bz2 -tar -xf ./ts3server.tar.bz2 -mv teamspeak3-server_linux_amd64/ /opt/teamspeak-server/ -touch /opt/teamspeak-server/.ts3server_license_accepted -echo "${RELEASE}" >~/.teamspeak-server -msg_ok "Setup Teamspeak Server" - -msg_info "Creating service" -cat </etc/systemd/system/teamspeak-server.service -[Unit] -Description=TeamSpeak3 Server -Wants=network-online.target -After=network.target - -[Service] -WorkingDirectory=/opt/teamspeak-server -User=root -Type=forking -ExecStart=/opt/teamspeak-server/ts3server_startscript.sh start -ExecStop=/opt/teamspeak-server/ts3server_startscript.sh stop -ExecReload=/opt/teamspeak-server/ts3server_startscript.sh restart -Restart=always -RestartSec=15 - -[Install] -WantedBy=multi-user.target -EOF -systemctl enable -q --now teamspeak-server -msg_ok "Created service" - -motd_ssh -customize - -msg_info "Cleaning up" -rm -f ~/ts3server.tar.bz* -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" From 5ceae638b56a94a4d0fa0173ecbb429fba2c8eb2 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 22 Jul 2025 13:59:54 +0000 Subject: [PATCH 463/463] Update .app files --- ct/headers/salt | 6 ------ ct/headers/teamspeak-server | 6 ------ 2 files changed, 12 deletions(-) delete mode 100644 ct/headers/salt delete mode 100644 ct/headers/teamspeak-server diff --git a/ct/headers/salt b/ct/headers/salt deleted file mode 100644 index 3b11949d..00000000 --- a/ct/headers/salt +++ /dev/null @@ -1,6 +0,0 @@ - _____ ____ - / ___/____ _/ / /_ - \__ \/ __ `/ / __/ - ___/ / /_/ / / /_ -/____/\__,_/_/\__/ - diff --git a/ct/headers/teamspeak-server b/ct/headers/teamspeak-server deleted file mode 100644 index 92c3a8e4..00000000 --- a/ct/headers/teamspeak-server +++ /dev/null @@ -1,6 +0,0 @@ - ______ __ _____ - /_ __/__ ____ _____ ___ _________ ___ ____ _/ /__ / ___/___ ______ _____ _____ - / / / _ \/ __ `/ __ `__ \/ ___/ __ \/ _ \/ __ `/ //_/_____\__ \/ _ \/ ___/ | / / _ \/ ___/ - / / / __/ /_/ / / / / / (__ ) /_/ / __/ /_/ / ,< /_____/__/ / __/ / | |/ / __/ / -/_/ \___/\__,_/_/ /_/ /_/____/ .___/\___/\__,_/_/|_| /____/\___/_/ |___/\___/_/ - /_/