From 996ad5aa0eb43c3dd828f60f20e0013238765437 Mon Sep 17 00:00:00 2001 From: Jason Green Date: Thu, 26 Jun 2025 21:16:02 -0700 Subject: [PATCH 001/129] 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/129] 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 da932c0473d2019d9bfb2c82dc7f39dbe064630a Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 27 Jun 2025 08:07:25 -0700 Subject: [PATCH 003/129] 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 004/129] 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 005/129] 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 006/129] 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 007/129] 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 008/129] 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 009/129] 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 010/129] 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 e00e6c6bb6cbed653c780a60103737d62ef14247 Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 27 Jun 2025 16:11:29 -0700 Subject: [PATCH 011/129] 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 012/129] 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 013/129] 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 014/129] 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 015/129] 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 016/129] 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 017/129] 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 018/129] 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 019/129] 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 020/129] 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 021/129] 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 022/129] 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 023/129] 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 024/129] 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 025/129] 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 026/129] 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 027/129] 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 028/129] 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 029/129] 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 030/129] 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 031/129] 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 032/129] 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 033/129] 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 034/129] 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 035/129] 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 036/129] 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 037/129] 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 038/129] 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 039/129] 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 040/129] 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 041/129] 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 042/129] 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 043/129] 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 044/129] 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 045/129] 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 046/129] 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 047/129] 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 048/129] 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 049/129] 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 050/129] 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 051/129] 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 052/129] 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 053/129] 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 054/129] 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 055/129] 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 056/129] 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 057/129] 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 058/129] 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 059/129] 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 060/129] 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 061/129] 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 062/129] 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 063/129] 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 064/129] 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 065/129] 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 066/129] 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 067/129] 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 068/129] 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 069/129] 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 070/129] 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 071/129] 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 072/129] 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 073/129] 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 074/129] 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 075/129] 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 076/129] 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 077/129] 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 078/129] 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 079/129] 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 080/129] 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 081/129] 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 082/129] 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 083/129] 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 084/129] 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 085/129] 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 086/129] 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 087/129] 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 088/129] 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 089/129] 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 090/129] 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 091/129] 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 092/129] 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 093/129] 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 094/129] 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 095/129] 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 096/129] 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 097/129] 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 098/129] 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 099/129] 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 100/129] 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 101/129] 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 102/129] 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 103/129] 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 104/129] 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 105/129] 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 106/129] 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 107/129] 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 108/129] 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 109/129] 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 110/129] 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 111/129] 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 112/129] 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 113/129] 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 114/129] 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 115/129] 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 116/129] 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 117/129] 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 118/129] 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 119/129] 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 120/129] 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 121/129] 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 122/129] 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 123/129] 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 124/129] 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 125/129] 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 126/129] 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 127/129] 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 128/129] 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 129/129] 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" } ]