diff --git a/ct/deferred/pixelfed.sh b/ct/deferred/pixelfed.sh deleted file mode 100644 index f9f6ba2e2..000000000 --- a/ct/deferred/pixelfed.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) -# Copyright (c) 2021-2026 community-scripts ORG -# Author: MickLesk (Canbiz) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: - -APP="Pixelfed" -var_tags="${var_tags:-pictures}" -var_disk="${var_disk:-7}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-2048}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - header_info - check_container_storage - check_container_resources - if [[ ! -d /opt/pixelfed ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - RELEASE=$(curl -fsSL https://api.github.com/repos/xxxx/xxxx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then - msg_info "Updating ${APP} to ${RELEASE}" - cd /opt - else - msg_ok "No update required. ${APP} is already at ${RELEASE}" - fi - exit -} - -start -build_container -description - -msg_ok "Completed successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. - ${BL}http://${IP}:8000${CL} \n" diff --git a/ct/rybbit.sh b/ct/deferred/rybbit.sh similarity index 100% rename from ct/rybbit.sh rename to ct/deferred/rybbit.sh diff --git a/ct/transmission-openvpn.sh b/ct/deferred/transmission-openvpn.sh similarity index 100% rename from ct/transmission-openvpn.sh rename to ct/deferred/transmission-openvpn.sh diff --git a/ct/gwn-manager.sh b/ct/gwn-manager.sh deleted file mode 100644 index 3c63e2c68..000000000 --- a/ct/gwn-manager.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2026 community-scripts ORG -# Author: Slaviša Arežina (tremor021) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://www.grandstream.com/products/networking-solutions/wi-fi-management/product/gwn-manager - -APP="GWN-Manager" -var_tags="${var_tags:-network;management}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-6144}" -var_disk="${var_disk:-8}" -var_os="${var_os:-debian}" -var_version="${var_version:-13}" -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 /gwn ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - - msg_ok "Application is updated via the web interface!" - exit -} - -start -build_container -description - -msg_ok "Completed successfully!\n" -echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" -echo -e "${INFO}${YW} Access it using the following URL:${CL}" -echo -e "${TAB}${GATEWAY}${BGN}https://${IP}:8443${CL}" diff --git a/ct/heimdall-dashboard.sh b/ct/heimdall-dashboard.sh deleted file mode 100644 index 6fe51c7ba..000000000 --- a/ct/heimdall-dashboard.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2026 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://heimdall.site/ - -APP="Heimdall-Dashboard" -var_tags="${var_tags:-dashboard}" -var_cpu="${var_cpu:-1}" -var_ram="${var_ram:-512}" -var_disk="${var_disk:-2}" -var_os="${var_os:-debian}" -var_version="${var_version:-13}" -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/Heimdall ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - - if check_for_gh_release "Heimdall" "linuxserver/Heimdall"; then - msg_info "Stopping Service" - systemctl stop heimdall - sleep 1 - msg_ok "Stopped Service" - - msg_info "Backing up Data" - cp -R /opt/Heimdall/database database-backup - cp -R /opt/Heimdall/public public-backup - sleep 1 - msg_ok "Backed up Data" - - setup_composer - fetch_and_deploy_gh_release "Heimdall" "linuxserver/Heimdall" "tarball" - - msg_info "Updating Heimdall-Dashboard" - cd /opt/Heimdall - export COMPOSER_ALLOW_SUPERUSER=1 - $STD composer dump-autoload - msg_ok "Updated Heimdall-Dashboard" - - msg_info "Restoring Data" - cd ~ - cp -R database-backup/* /opt/Heimdall/database - cp -R public-backup/* /opt/Heimdall/public - sleep 1 - msg_ok "Restored Data" - - msg_info "Cleaning Up" - rm -rf {public-backup,database-backup} - sleep 1 - msg_ok "Cleaned Up" - - msg_info "Starting Service" - systemctl start heimdall.service - sleep 2 - msg_ok "Started Service" - msg_ok "Updated successfully!" - fi - exit -} - -start -build_container -description - -msg_ok "Completed successfully!\n" -echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" -echo -e "${INFO}${YW} Access it using the following URL:${CL}" -echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:7990${CL}" diff --git a/ct/linkwarden.sh b/ct/linkwarden.sh deleted file mode 100644 index 8753ce8f4..000000000 --- a/ct/linkwarden.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2026 community-scripts ORG -# Author: MickLesk (CanbiZ) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://linkwarden.app/ - -APP="Linkwarden" -var_tags="${var_tags:-bookmark}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-4096}" -var_disk="${var_disk:-12}" -var_os="${var_os:-ubuntu}" -var_version="${var_version:-24.04}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - header_info - check_container_storage - check_container_resources - if [[ ! -d /opt/linkwarden ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - if check_for_gh_release "linkwarden" "linkwarden/linkwarden"; then - NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs - msg_info "Stopping Service" - systemctl stop linkwarden - msg_ok "Stopped Service" - - RUST_CRATES="monolith" setup_rust - - msg_info "Backing up data" - mv /opt/linkwarden/.env /opt/.env - [ -d /opt/linkwarden/data ] && mv /opt/linkwarden/data /opt/data.bak - rm -rf /opt/linkwarden - msg_ok "Backed up data" - - fetch_and_deploy_gh_release "linkwarden" "linkwarden/linkwarden" - - msg_info "Updating ${APP}" - cd /opt/linkwarden - $STD yarn - $STD npx playwright install-deps - $STD yarn playwright install - mv /opt/.env /opt/linkwarden/.env - $STD yarn prisma:generate - $STD yarn web:build - $STD yarn prisma:deploy - [ -d /opt/data.bak ] && mv /opt/data.bak /opt/linkwarden/data - rm -rf ~/.cargo/registry ~/.cargo/git ~/.cargo/.package-cache - rm -rf /root/.cache/yarn - rm -rf /opt/linkwarden/.next/cache - msg_ok "Updated ${APP}" - - msg_info "Starting Service" - systemctl start linkwarden - msg_ok "Started Service" - msg_ok "Updated successfully!" - fi - exit -} - -start -build_container -description - -msg_ok "Completed successfully!\n" -echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" -echo -e "${INFO}${YW} Access it using the following URL:${CL}" -echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}" diff --git a/ct/plex.sh b/ct/plex.sh deleted file mode 100644 index 00590c47c..000000000 --- a/ct/plex.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2026 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://www.plex.tv/ - -APP="Plex" -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}" -var_gpu="${var_gpu:-yes}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - header_info - check_container_storage - check_container_resources - if [[ ! -f /etc/apt/sources.list.d/plexmediaserver.list ]] && - [[ ! -f /etc/apt/sources.list.d/plexmediaserver.sources ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select \nplexupdate info >> https://github.com/mrworf/plexupdate" 10 59 2 \ - "1" "Update LXC" ON \ - "2" "Install plexupdate" OFF \ - 3>&1 1>&2 2>&3) - if [ "$UPD" == "1" ]; then - msg_info "Updating Plex LXC" - $STD apt update - $STD apt -y upgrade - msg_ok "Updated Plex LXC" - msg_ok "Updated successfully!" - exit - fi - if [ "$UPD" == "2" ]; then - set +e - bash -c "$(curl -fsSL https://raw.githubusercontent.com/mrworf/plexupdate/master/extras/installer.sh)" - msg_ok "Updated successfully!" - exit - fi -} - -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}:32400/web${CL}" diff --git a/ct/plex2.sh b/ct/plex2.sh deleted file mode 100644 index dff1fdd62..000000000 --- a/ct/plex2.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) -# Copyright (c) 2021-2026 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://www.plex.tv/ - -APP="Plex2" -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}" -var_gpu="${var_gpu:-yes}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - header_info - check_container_storage - check_container_resources - if [[ ! -f /etc/apt/sources.list.d/plexmediaserver.list ]] && - [[ ! -f /etc/apt/sources.list.d/plexmediaserver.sources ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select \nplexupdate info >> https://github.com/mrworf/plexupdate" 10 59 2 \ - "1" "Update LXC" ON \ - "2" "Install plexupdate" OFF \ - 3>&1 1>&2 2>&3) - if [ "$UPD" == "1" ]; then - msg_info "Updating Plex" - $STD apt update - $STD apt -y upgrade - msg_ok "Updated Plex" - msg_ok "Updated successfully!" - exit - fi - if [ "$UPD" == "2" ]; then - set +e - bash -c "$(curl -fsSL https://raw.githubusercontent.com/mrworf/plexupdate/master/extras/installer.sh)" - msg_ok "Updated successfully!" - exit - fi -} - -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}:32400/web${CL}" diff --git a/install/transmission-openvpn-install.sh b/install/deferred/transmission-openvpn-install.sh similarity index 100% rename from install/transmission-openvpn-install.sh rename to install/deferred/transmission-openvpn-install.sh diff --git a/install/piler-install.sh b/install/piler-install.sh index f867e54be..1eeadff04 100644 --- a/install/piler-install.sh +++ b/install/piler-install.sh @@ -225,6 +225,7 @@ if [ ! -f /var/www/piler/config-site.php ]; then \$config['HEADER_LINE_TO_HIDE'] = 'X-Envelope-To:'; ?> EOF +fi chown -R piler:piler /var/www/piler chmod 755 /var/www/piler diff --git a/install/plex-install.sh b/install/plex-install.sh deleted file mode 100644 index 8e786f0cc..000000000 --- a/install/plex-install.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2026 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://www.plex.tv/ - -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 -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} -if [[ -d /dev/dri ]]; then - chgrp video /dev/dri 2>/dev/null || true - chmod 755 /dev/dri 2>/dev/null || true - chmod 660 /dev/dri/* 2>/dev/null || true - $STD adduser "$(id -u -n)" video - $STD adduser "$(id -u -n)" render -fi -msg_ok "Set Up Hardware Acceleration" - -msg_info "Setting Up Plex Media Server Repository" -curl -fsSL https://downloads.plex.tv/plex-keys/PlexSign.key | tee /usr/share/keyrings/PlexSign.asc >/dev/null -cat </etc/apt/sources.list.d/plexmediaserver.sources -Types: deb -URIs: https://downloads.plex.tv/repo/deb/ -Suites: public -Components: main -Signed-By: /usr/share/keyrings/PlexSign.asc -EOF -msg_ok "Set Up Plex Media Server Repository" - -msg_info "Installing Plex Media Server" -$STD apt update -$STD apt -o Dpkg::Options::="--force-confold" install -y plexmediaserver -if [[ "$CTTYPE" == "0" ]]; then - sed -i -e 's/^ssl-cert:x:104:plex$/render:x:104:root,plex/' -e 's/^render:x:108:root$/ssl-cert:x:108:plex/' /etc/group -else - sed -i -e 's/^ssl-cert:x:104:plex$/render:x:104:plex/' -e 's/^render:x:108:$/ssl-cert:x:108:/' /etc/group -fi -msg_ok "Installed Plex Media Server" - -motd_ssh -customize -cleanup_lxc diff --git a/install/plex2-install.sh b/install/plex2-install.sh deleted file mode 100644 index bb29392c7..000000000 --- a/install/plex2-install.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2026 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://www.plex.tv/ - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -setup_hwaccel - -msg_info "Setting Up Plex Media Server Repository" -curl -fsSL https://downloads.plex.tv/plex-keys/PlexSign.key | tee /usr/share/keyrings/PlexSign.asc >/dev/null -cat </etc/apt/sources.list.d/plexmediaserver.sources -Types: deb -URIs: https://downloads.plex.tv/repo/deb/ -Suites: public -Components: main -Signed-By: /usr/share/keyrings/PlexSign.asc -EOF -msg_ok "Set Up Plex Media Server Repository" - -msg_info "Installing Plex Media Server" -$STD apt update -$STD apt -o Dpkg::Options::="--force-confold" install -y plexmediaserver -if [[ "$CTTYPE" == "0" ]]; then - sed -i -e 's/^ssl-cert:x:104:plex$/render:x:104:root,plex/' -e 's/^render:x:108:root$/ssl-cert:x:108:plex/' /etc/group -else - sed -i -e 's/^ssl-cert:x:104:plex$/render:x:104:plex/' -e 's/^render:x:108:$/ssl-cert:x:108:/' /etc/group -fi -msg_ok "Installed Plex Media Server" - -motd_ssh -customize -cleanup_lxc diff --git a/misc/install.func b/misc/install.func index 41168a0f0..591404363 100644 --- a/misc/install.func +++ b/misc/install.func @@ -49,134 +49,134 @@ INIT_SYSTEM="" # systemd, openrc, sysvinit # OS_TYPE, OS_FAMILY, OS_VERSION, PKG_MANAGER, INIT_SYSTEM # ------------------------------------------------------------------------------ detect_os() { - if [[ -f /etc/os-release ]]; then - # shellcheck disable=SC1091 - . /etc/os-release - OS_TYPE="${ID:-unknown}" - OS_VERSION="${VERSION_ID:-unknown}" - elif [[ -f /etc/alpine-release ]]; then - OS_TYPE="alpine" - OS_VERSION=$(cat /etc/alpine-release) - elif [[ -f /etc/debian_version ]]; then - OS_TYPE="debian" - OS_VERSION=$(cat /etc/debian_version) - elif [[ -f /etc/redhat-release ]]; then - OS_TYPE="centos" - OS_VERSION=$(grep -oE '[0-9]+\.[0-9]+' /etc/redhat-release | head -1) - elif [[ -f /etc/arch-release ]]; then - OS_TYPE="arch" - OS_VERSION="rolling" - elif [[ -f /etc/gentoo-release ]]; then - OS_TYPE="gentoo" - OS_VERSION=$(cat /etc/gentoo-release | grep -oE '[0-9.]+') - else - OS_TYPE="unknown" - OS_VERSION="unknown" - fi + if [[ -f /etc/os-release ]]; then + # shellcheck disable=SC1091 + . /etc/os-release + OS_TYPE="${ID:-unknown}" + OS_VERSION="${VERSION_ID:-unknown}" + elif [[ -f /etc/alpine-release ]]; then + OS_TYPE="alpine" + OS_VERSION=$(cat /etc/alpine-release) + elif [[ -f /etc/debian_version ]]; then + OS_TYPE="debian" + OS_VERSION=$(cat /etc/debian_version) + elif [[ -f /etc/redhat-release ]]; then + OS_TYPE="centos" + OS_VERSION=$(grep -oE '[0-9]+\.[0-9]+' /etc/redhat-release | head -1) + elif [[ -f /etc/arch-release ]]; then + OS_TYPE="arch" + OS_VERSION="rolling" + elif [[ -f /etc/gentoo-release ]]; then + OS_TYPE="gentoo" + OS_VERSION=$(cat /etc/gentoo-release | grep -oE '[0-9.]+') + else + OS_TYPE="unknown" + OS_VERSION="unknown" + fi - # Normalize OS type and determine family - case "$OS_TYPE" in - debian) - OS_FAMILY="debian" - PKG_MANAGER="apt" - ;; - ubuntu) - OS_FAMILY="debian" - PKG_MANAGER="apt" - ;; - devuan) - OS_FAMILY="debian" - PKG_MANAGER="apt" - ;; - alpine) - OS_FAMILY="alpine" - PKG_MANAGER="apk" - ;; - fedora) - OS_FAMILY="rhel" - PKG_MANAGER="dnf" - ;; - rocky | rockylinux) - OS_TYPE="rocky" - OS_FAMILY="rhel" - PKG_MANAGER="dnf" - ;; - alma | almalinux) - OS_TYPE="alma" - OS_FAMILY="rhel" - PKG_MANAGER="dnf" - ;; - centos) - OS_FAMILY="rhel" - # CentOS 7 uses yum, 8+ uses dnf - if [[ "${OS_VERSION%%.*}" -ge 8 ]]; then - PKG_MANAGER="dnf" - else - PKG_MANAGER="yum" - fi - ;; - rhel) - OS_FAMILY="rhel" - PKG_MANAGER="dnf" - ;; - openeuler) - OS_FAMILY="rhel" - PKG_MANAGER="dnf" - ;; - opensuse* | sles) - OS_TYPE="opensuse" - OS_FAMILY="suse" - PKG_MANAGER="zypper" - ;; - gentoo) - OS_FAMILY="gentoo" - PKG_MANAGER="emerge" - ;; - *) - OS_FAMILY="unknown" - PKG_MANAGER="unknown" - ;; - esac - - # Detect init system - if command -v systemctl &>/dev/null && [[ -d /run/systemd/system ]]; then - INIT_SYSTEM="systemd" - elif command -v rc-service &>/dev/null || [[ -d /etc/init.d && -f /sbin/openrc ]]; then - INIT_SYSTEM="openrc" - elif [[ -f /etc/inittab ]]; then - INIT_SYSTEM="sysvinit" + # Normalize OS type and determine family + case "$OS_TYPE" in + debian) + OS_FAMILY="debian" + PKG_MANAGER="apt" + ;; + ubuntu) + OS_FAMILY="debian" + PKG_MANAGER="apt" + ;; + devuan) + OS_FAMILY="debian" + PKG_MANAGER="apt" + ;; + alpine) + OS_FAMILY="alpine" + PKG_MANAGER="apk" + ;; + fedora) + OS_FAMILY="rhel" + PKG_MANAGER="dnf" + ;; + rocky | rockylinux) + OS_TYPE="rocky" + OS_FAMILY="rhel" + PKG_MANAGER="dnf" + ;; + alma | almalinux) + OS_TYPE="alma" + OS_FAMILY="rhel" + PKG_MANAGER="dnf" + ;; + centos) + OS_FAMILY="rhel" + # CentOS 7 uses yum, 8+ uses dnf + if [[ "${OS_VERSION%%.*}" -ge 8 ]]; then + PKG_MANAGER="dnf" else - INIT_SYSTEM="unknown" + PKG_MANAGER="yum" fi + ;; + rhel) + OS_FAMILY="rhel" + PKG_MANAGER="dnf" + ;; + openeuler) + OS_FAMILY="rhel" + PKG_MANAGER="dnf" + ;; + opensuse* | sles) + OS_TYPE="opensuse" + OS_FAMILY="suse" + PKG_MANAGER="zypper" + ;; + gentoo) + OS_FAMILY="gentoo" + PKG_MANAGER="emerge" + ;; + *) + OS_FAMILY="unknown" + PKG_MANAGER="unknown" + ;; + esac + + # Detect init system + if command -v systemctl &>/dev/null && [[ -d /run/systemd/system ]]; then + INIT_SYSTEM="systemd" + elif command -v rc-service &>/dev/null || [[ -d /etc/init.d && -f /sbin/openrc ]]; then + INIT_SYSTEM="openrc" + elif [[ -f /etc/inittab ]]; then + INIT_SYSTEM="sysvinit" + else + INIT_SYSTEM="unknown" + fi } # ------------------------------------------------------------------------------ # Bootstrap: Ensure curl is available and source core functions # ------------------------------------------------------------------------------ _bootstrap() { - # Minimal bootstrap to get curl installed - if ! command -v curl &>/dev/null; then - printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 - if command -v apt-get &>/dev/null; then - apt-get update &>/dev/null && apt-get install -y curl &>/dev/null - elif command -v apk &>/dev/null; then - apk update &>/dev/null && apk add curl &>/dev/null - elif command -v dnf &>/dev/null; then - dnf install -y curl &>/dev/null - elif command -v yum &>/dev/null; then - yum install -y curl &>/dev/null - elif command -v zypper &>/dev/null; then - zypper install -y curl &>/dev/null - elif command -v emerge &>/dev/null; then - emerge --quiet net-misc/curl &>/dev/null - fi + # Minimal bootstrap to get curl installed + if ! command -v curl &>/dev/null; then + printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 + if command -v apt-get &>/dev/null; then + apt-get update &>/dev/null && apt-get install -y curl &>/dev/null + elif command -v apk &>/dev/null; then + apk update &>/dev/null && apk add curl &>/dev/null + elif command -v dnf &>/dev/null; then + dnf install -y curl &>/dev/null + elif command -v yum &>/dev/null; then + yum install -y curl &>/dev/null + elif command -v zypper &>/dev/null; then + zypper install -y curl &>/dev/null + elif command -v emerge &>/dev/null; then + emerge --quiet net-misc/curl &>/dev/null fi + fi - # Source core functions - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/error_handler.func) - load_functions - catch_errors + # Source core functions + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/error_handler.func) + load_functions + catch_errors } # Run bootstrap and OS detection @@ -193,30 +193,30 @@ detect_os # Updates package manager cache/database # ------------------------------------------------------------------------------ pkg_update() { - case "$PKG_MANAGER" in - apt) - $STD apt-get update - ;; - apk) - $STD apk update - ;; - dnf) - $STD dnf makecache - ;; - yum) - $STD yum makecache - ;; - zypper) - $STD zypper refresh - ;; - emerge) - $STD emerge --sync - ;; - *) - msg_error "Unknown package manager: $PKG_MANAGER" - return 1 - ;; - esac + case "$PKG_MANAGER" in + apt) + $STD apt-get update + ;; + apk) + $STD apk update + ;; + dnf) + $STD dnf makecache + ;; + yum) + $STD yum makecache + ;; + zypper) + $STD zypper refresh + ;; + emerge) + $STD emerge --sync + ;; + *) + msg_error "Unknown package manager: $PKG_MANAGER" + return 1 + ;; + esac } # ------------------------------------------------------------------------------ @@ -225,30 +225,30 @@ pkg_update() { # Upgrades all installed packages # ------------------------------------------------------------------------------ pkg_upgrade() { - case "$PKG_MANAGER" in - apt) - $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade - ;; - apk) - $STD apk -U upgrade - ;; - dnf) - $STD dnf -y upgrade - ;; - yum) - $STD yum -y update - ;; - zypper) - $STD zypper -n update - ;; - emerge) - $STD emerge --quiet --update --deep @world - ;; - *) - msg_error "Unknown package manager: $PKG_MANAGER" - return 1 - ;; - esac + case "$PKG_MANAGER" in + apt) + $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade + ;; + apk) + $STD apk -U upgrade + ;; + dnf) + $STD dnf -y upgrade + ;; + yum) + $STD yum -y update + ;; + zypper) + $STD zypper -n update + ;; + emerge) + $STD emerge --quiet --update --deep @world + ;; + *) + msg_error "Unknown package manager: $PKG_MANAGER" + return 1 + ;; + esac } # ------------------------------------------------------------------------------ @@ -259,33 +259,33 @@ pkg_upgrade() { # packages - List of packages to install # ------------------------------------------------------------------------------ pkg_install() { - local packages=("$@") - [[ ${#packages[@]} -eq 0 ]] && return 0 + local packages=("$@") + [[ ${#packages[@]} -eq 0 ]] && return 0 - case "$PKG_MANAGER" in - apt) - $STD apt-get install -y "${packages[@]}" - ;; - apk) - $STD apk add --no-cache "${packages[@]}" - ;; - dnf) - $STD dnf install -y "${packages[@]}" - ;; - yum) - $STD yum install -y "${packages[@]}" - ;; - zypper) - $STD zypper install -y "${packages[@]}" - ;; - emerge) - $STD emerge --quiet "${packages[@]}" - ;; - *) - msg_error "Unknown package manager: $PKG_MANAGER" - return 1 - ;; - esac + case "$PKG_MANAGER" in + apt) + $STD apt-get install -y "${packages[@]}" + ;; + apk) + $STD apk add --no-cache "${packages[@]}" + ;; + dnf) + $STD dnf install -y "${packages[@]}" + ;; + yum) + $STD yum install -y "${packages[@]}" + ;; + zypper) + $STD zypper install -y "${packages[@]}" + ;; + emerge) + $STD emerge --quiet "${packages[@]}" + ;; + *) + msg_error "Unknown package manager: $PKG_MANAGER" + return 1 + ;; + esac } # ------------------------------------------------------------------------------ @@ -294,33 +294,33 @@ pkg_install() { # Removes one or more packages # ------------------------------------------------------------------------------ pkg_remove() { - local packages=("$@") - [[ ${#packages[@]} -eq 0 ]] && return 0 + local packages=("$@") + [[ ${#packages[@]} -eq 0 ]] && return 0 - case "$PKG_MANAGER" in - apt) - $STD apt-get remove -y "${packages[@]}" - ;; - apk) - $STD apk del "${packages[@]}" - ;; - dnf) - $STD dnf remove -y "${packages[@]}" - ;; - yum) - $STD yum remove -y "${packages[@]}" - ;; - zypper) - $STD zypper remove -y "${packages[@]}" - ;; - emerge) - $STD emerge --quiet --unmerge "${packages[@]}" - ;; - *) - msg_error "Unknown package manager: $PKG_MANAGER" - return 1 - ;; - esac + case "$PKG_MANAGER" in + apt) + $STD apt-get remove -y "${packages[@]}" + ;; + apk) + $STD apk del "${packages[@]}" + ;; + dnf) + $STD dnf remove -y "${packages[@]}" + ;; + yum) + $STD yum remove -y "${packages[@]}" + ;; + zypper) + $STD zypper remove -y "${packages[@]}" + ;; + emerge) + $STD emerge --quiet --unmerge "${packages[@]}" + ;; + *) + msg_error "Unknown package manager: $PKG_MANAGER" + return 1 + ;; + esac } # ------------------------------------------------------------------------------ @@ -329,31 +329,31 @@ pkg_remove() { # Cleans package manager cache to free space # ------------------------------------------------------------------------------ pkg_clean() { - case "$PKG_MANAGER" in - apt) - $STD apt-get autoremove -y - $STD apt-get autoclean - ;; - apk) - $STD apk cache clean - ;; - dnf) - $STD dnf clean all - $STD dnf autoremove -y - ;; - yum) - $STD yum clean all - ;; - zypper) - $STD zypper clean - ;; - emerge) - $STD emerge --quiet --depclean - ;; - *) - return 0 - ;; - esac + case "$PKG_MANAGER" in + apt) + $STD apt-get autoremove -y + $STD apt-get autoclean + ;; + apk) + $STD apk cache clean + ;; + dnf) + $STD dnf clean all + $STD dnf autoremove -y + ;; + yum) + $STD yum clean all + ;; + zypper) + $STD zypper clean + ;; + emerge) + $STD emerge --quiet --depclean + ;; + *) + return 0 + ;; + esac } # ============================================================================== @@ -366,28 +366,28 @@ pkg_clean() { # Enables a service to start at boot # ------------------------------------------------------------------------------ svc_enable() { - local service="$1" - [[ -z "$service" ]] && return 1 + local service="$1" + [[ -z "$service" ]] && return 1 - case "$INIT_SYSTEM" in - systemd) - $STD systemctl enable "$service" - ;; - openrc) - $STD rc-update add "$service" default - ;; - sysvinit) - if command -v update-rc.d &>/dev/null; then - $STD update-rc.d "$service" defaults - elif command -v chkconfig &>/dev/null; then - $STD chkconfig "$service" on - fi - ;; - *) - msg_warn "Unknown init system, cannot enable $service" - return 1 - ;; - esac + case "$INIT_SYSTEM" in + systemd) + $STD systemctl enable "$service" + ;; + openrc) + $STD rc-update add "$service" default + ;; + sysvinit) + if command -v update-rc.d &>/dev/null; then + $STD update-rc.d "$service" defaults + elif command -v chkconfig &>/dev/null; then + $STD chkconfig "$service" on + fi + ;; + *) + msg_warn "Unknown init system, cannot enable $service" + return 1 + ;; + esac } # ------------------------------------------------------------------------------ @@ -396,27 +396,27 @@ svc_enable() { # Disables a service from starting at boot # ------------------------------------------------------------------------------ svc_disable() { - local service="$1" - [[ -z "$service" ]] && return 1 + local service="$1" + [[ -z "$service" ]] && return 1 - case "$INIT_SYSTEM" in - systemd) - $STD systemctl disable "$service" - ;; - openrc) - $STD rc-update del "$service" default 2>/dev/null || true - ;; - sysvinit) - if command -v update-rc.d &>/dev/null; then - $STD update-rc.d "$service" remove - elif command -v chkconfig &>/dev/null; then - $STD chkconfig "$service" off - fi - ;; - *) - return 1 - ;; - esac + case "$INIT_SYSTEM" in + systemd) + $STD systemctl disable "$service" + ;; + openrc) + $STD rc-update del "$service" default 2>/dev/null || true + ;; + sysvinit) + if command -v update-rc.d &>/dev/null; then + $STD update-rc.d "$service" remove + elif command -v chkconfig &>/dev/null; then + $STD chkconfig "$service" off + fi + ;; + *) + return 1 + ;; + esac } # ------------------------------------------------------------------------------ @@ -425,23 +425,23 @@ svc_disable() { # Starts a service immediately # ------------------------------------------------------------------------------ svc_start() { - local service="$1" - [[ -z "$service" ]] && return 1 + local service="$1" + [[ -z "$service" ]] && return 1 - case "$INIT_SYSTEM" in - systemd) - $STD systemctl start "$service" - ;; - openrc) - $STD rc-service "$service" start - ;; - sysvinit) - $STD /etc/init.d/"$service" start - ;; - *) - return 1 - ;; - esac + case "$INIT_SYSTEM" in + systemd) + $STD systemctl start "$service" + ;; + openrc) + $STD rc-service "$service" start + ;; + sysvinit) + $STD /etc/init.d/"$service" start + ;; + *) + return 1 + ;; + esac } # ------------------------------------------------------------------------------ @@ -450,23 +450,23 @@ svc_start() { # Stops a running service # ------------------------------------------------------------------------------ svc_stop() { - local service="$1" - [[ -z "$service" ]] && return 1 + local service="$1" + [[ -z "$service" ]] && return 1 - case "$INIT_SYSTEM" in - systemd) - $STD systemctl stop "$service" - ;; - openrc) - $STD rc-service "$service" stop - ;; - sysvinit) - $STD /etc/init.d/"$service" stop - ;; - *) - return 1 - ;; - esac + case "$INIT_SYSTEM" in + systemd) + $STD systemctl stop "$service" + ;; + openrc) + $STD rc-service "$service" stop + ;; + sysvinit) + $STD /etc/init.d/"$service" stop + ;; + *) + return 1 + ;; + esac } # ------------------------------------------------------------------------------ @@ -475,23 +475,23 @@ svc_stop() { # Restarts a service # ------------------------------------------------------------------------------ svc_restart() { - local service="$1" - [[ -z "$service" ]] && return 1 + local service="$1" + [[ -z "$service" ]] && return 1 - case "$INIT_SYSTEM" in - systemd) - $STD systemctl restart "$service" - ;; - openrc) - $STD rc-service "$service" restart - ;; - sysvinit) - $STD /etc/init.d/"$service" restart - ;; - *) - return 1 - ;; - esac + case "$INIT_SYSTEM" in + systemd) + $STD systemctl restart "$service" + ;; + openrc) + $STD rc-service "$service" restart + ;; + sysvinit) + $STD /etc/init.d/"$service" restart + ;; + *) + return 1 + ;; + esac } # ------------------------------------------------------------------------------ @@ -500,23 +500,23 @@ svc_restart() { # Gets service status (returns 0 if running) # ------------------------------------------------------------------------------ svc_status() { - local service="$1" - [[ -z "$service" ]] && return 1 + local service="$1" + [[ -z "$service" ]] && return 1 - case "$INIT_SYSTEM" in - systemd) - systemctl is-active --quiet "$service" - ;; - openrc) - rc-service "$service" status &>/dev/null - ;; - sysvinit) - /etc/init.d/"$service" status &>/dev/null - ;; - *) - return 1 - ;; - esac + case "$INIT_SYSTEM" in + systemd) + systemctl is-active --quiet "$service" + ;; + openrc) + rc-service "$service" status &>/dev/null + ;; + sysvinit) + /etc/init.d/"$service" status &>/dev/null + ;; + *) + return 1 + ;; + esac } # ------------------------------------------------------------------------------ @@ -525,15 +525,15 @@ svc_status() { # Reloads init system daemon configuration (for systemd) # ------------------------------------------------------------------------------ svc_reload_daemon() { - case "$INIT_SYSTEM" in - systemd) - $STD systemctl daemon-reload - ;; - *) - # Other init systems don't need this - return 0 - ;; - esac + case "$INIT_SYSTEM" in + systemd) + $STD systemctl daemon-reload + ;; + *) + # Other init systems don't need this + return 0 + ;; + esac } # ============================================================================== @@ -547,24 +547,24 @@ svc_reload_daemon() { # Returns: IP address string # ------------------------------------------------------------------------------ get_ip() { - local ip="" + local ip="" - # Try hostname -I first (most common) - if command -v hostname &>/dev/null; then - ip=$(hostname -I 2>/dev/null | awk '{print $1}') - fi + # Try hostname -I first (most common) + if command -v hostname &>/dev/null; then + ip=$(hostname -I 2>/dev/null | awk '{print $1}') + fi - # Fallback to ip command - if [[ -z "$ip" ]] && command -v ip &>/dev/null; then - ip=$(ip -4 addr show scope global | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -1) - fi + # Fallback to ip command + if [[ -z "$ip" ]] && command -v ip &>/dev/null; then + ip=$(ip -4 addr show scope global | awk '/inet /{print $2}' | cut -d/ -f1 | head -1) + fi - # Fallback to ifconfig - if [[ -z "$ip" ]] && command -v ifconfig &>/dev/null; then - ip=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -1) - fi + # Fallback to ifconfig + if [[ -z "$ip" ]] && command -v ifconfig &>/dev/null; then + ip=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -1) + fi - echo "$ip" + echo "$ip" } # ------------------------------------------------------------------------------ @@ -574,25 +574,25 @@ get_ip() { # If IPV6_METHOD=disable: disables IPv6 via sysctl # ------------------------------------------------------------------------------ verb_ip6() { - set_std_mode # Set STD mode based on VERBOSE + set_std_mode # Set STD mode based on VERBOSE - if [[ "${IPV6_METHOD:-}" == "disable" ]]; then - msg_info "Disabling IPv6 (this may affect some services)" - mkdir -p /etc/sysctl.d - cat >/etc/sysctl.d/99-disable-ipv6.conf </etc/sysctl.d/99-disable-ipv6.conf </dev/null || true - fi - msg_ok "Disabled IPv6" + # For OpenRC, ensure sysctl runs at boot + if [[ "$INIT_SYSTEM" == "openrc" ]]; then + $STD rc-update add sysctl default 2>/dev/null || true fi + msg_ok "Disabled IPv6" + fi } # ------------------------------------------------------------------------------ @@ -604,36 +604,36 @@ EOF # - Disables network wait services # ------------------------------------------------------------------------------ setting_up_container() { - msg_info "Setting up Container OS" + msg_info "Setting up Container OS" - # Wait for network - local i - for ((i = RETRY_NUM; i > 0; i--)); do - if [[ -n "$(get_ip)" ]]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep "$RETRY_EVERY" - done - - if [[ -z "$(get_ip)" ]]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e "${NETWORK}Check Network Settings" - exit 1 + # Wait for network + local i + for ((i = RETRY_NUM; i > 0; i--)); do + if [[ -n "$(get_ip)" ]]; then + break fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep "$RETRY_EVERY" + done - # Remove Python EXTERNALLY-MANAGED restriction (Debian 12+, Ubuntu 23.04+) - rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED 2>/dev/null || true + if [[ -z "$(get_ip)" ]]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e "${NETWORK}Check Network Settings" + exit 1 + fi - # Disable network wait services for faster boot - case "$INIT_SYSTEM" in - systemd) - systemctl disable -q --now systemd-networkd-wait-online.service 2>/dev/null || true - ;; - esac + # Remove Python EXTERNALLY-MANAGED restriction (Debian 12+, Ubuntu 23.04+) + rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED 2>/dev/null || true - msg_ok "Set up Container OS" - msg_ok "Network Connected: ${BL}$(get_ip)" + # Disable network wait services for faster boot + case "$INIT_SYSTEM" in + systemd) + systemctl disable -q --now systemd-networkd-wait-online.service 2>/dev/null || true + ;; + esac + + msg_ok "Set up Container OS" + msg_ok "Network Connected: ${BL}$(get_ip)" } # ------------------------------------------------------------------------------ @@ -643,65 +643,65 @@ setting_up_container() { # Tests connectivity to DNS servers and verifies DNS resolution # ------------------------------------------------------------------------------ network_check() { - set +e - trap - ERR - local ipv4_connected=false - local ipv6_connected=false - sleep 1 + set +e + trap - ERR + local ipv4_connected=false + local ipv6_connected=false + sleep 1 - # Check IPv4 connectivity - 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 + 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 (if ping6 exists) + if command -v ping6 &>/dev/null; then + if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null || ping6 -c 1 -W 1 2001:4860:4860::8888 &>/dev/null; then + msg_ok "IPv6 Internet Connected" + ipv6_connected=true else - msg_error "IPv4 Internet Not Connected" + msg_error "IPv6 Internet Not Connected" fi + fi - # Check IPv6 connectivity (if ping6 exists) - if command -v ping6 &>/dev/null; then - if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null || ping6 -c 1 -W 1 2001:4860:4860::8888 &>/dev/null; then - msg_ok "IPv6 Internet Connected" - ipv6_connected=true - else - msg_error "IPv6 Internet Not Connected" - fi - fi - - # Prompt if both fail - 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 - - # DNS resolution checks - local GIT_HOSTS=("github.com" "raw.githubusercontent.com" "git.community-scripts.org") - local GIT_STATUS="Git DNS:" - local DNS_FAILED=false - - for HOST in "${GIT_HOSTS[@]}"; do - local RESOLVEDIP - RESOLVEDIP=$(getent hosts "$HOST" 2>/dev/null | awk '{ print $1 }' | head -n1) - if [[ -z "$RESOLVEDIP" ]]; then - GIT_STATUS+=" $HOST:(${DNSFAIL:-FAIL})" - DNS_FAILED=true - else - GIT_STATUS+=" $HOST:(${DNSOK:-OK})" - fi - done - - if [[ "$DNS_FAILED" == true ]]; then - fatal "$GIT_STATUS" + # Prompt if both fail + 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_ok "$GIT_STATUS" + echo -e "${NETWORK}Check Network Settings" + exit 1 fi + fi - set -e - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + # DNS resolution checks + local GIT_HOSTS=("github.com" "raw.githubusercontent.com" "git.community-scripts.org") + local GIT_STATUS="Git DNS:" + local DNS_FAILED=false + + for HOST in "${GIT_HOSTS[@]}"; do + local RESOLVEDIP + RESOLVEDIP=$(getent hosts "$HOST" 2>/dev/null | awk '{ print $1 }' | head -n1) + if [[ -z "$RESOLVEDIP" ]]; then + GIT_STATUS+=" $HOST:(${DNSFAIL:-FAIL})" + DNS_FAILED=true + else + GIT_STATUS+=" $HOST:(${DNSOK:-OK})" + fi + done + + if [[ "$DNS_FAILED" == true ]]; then + fatal "$GIT_STATUS" + else + msg_ok "$GIT_STATUS" + fi + + set -e + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } # ============================================================================== @@ -714,12 +714,12 @@ network_check() { # Updates container OS and sources appropriate tools.func # ------------------------------------------------------------------------------ update_os() { - msg_info "Updating Container OS" + msg_info "Updating Container OS" - # Configure APT cacher proxy if enabled (Debian/Ubuntu only) - if [[ "$PKG_MANAGER" == "apt" && "${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 + # Configure APT cacher proxy if enabled (Debian/Ubuntu only) + if [[ "$PKG_MANAGER" == "apt" && "${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" @@ -727,27 +727,27 @@ else echo -n "DIRECT" fi EOF - chmod +x /usr/local/bin/apt-proxy-detect.sh - fi + chmod +x /usr/local/bin/apt-proxy-detect.sh + fi - # Update and upgrade - pkg_update - pkg_upgrade + # Update and upgrade + pkg_update + pkg_upgrade - # Remove Python EXTERNALLY-MANAGED restriction - rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED 2>/dev/null || true + # Remove Python EXTERNALLY-MANAGED restriction + rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED 2>/dev/null || true - msg_ok "Updated Container OS" + msg_ok "Updated Container OS" - # Source appropriate tools.func based on OS - case "$OS_FAMILY" in - alpine) - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-tools.func) - ;; - *) - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) - ;; - esac + # Source appropriate tools.func based on OS + case "$OS_FAMILY" in + alpine) + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-tools.func) + ;; + *) + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) + ;; + esac } # ============================================================================== @@ -760,79 +760,79 @@ EOF # Configures Message of the Day and SSH settings # ------------------------------------------------------------------------------ motd_ssh() { - # Set terminal to 256-color mode - grep -qxF "export TERM='xterm-256color'" /root/.bashrc 2>/dev/null || echo "export TERM='xterm-256color'" >>/root/.bashrc + # Set terminal to 256-color mode + grep -qxF "export TERM='xterm-256color'" /root/.bashrc 2>/dev/null || echo "export TERM='xterm-256color'" >>/root/.bashrc - # Get OS information - local os_name="$OS_TYPE" - local os_version="$OS_VERSION" + # Get OS information + local os_name="$OS_TYPE" + local os_version="$OS_VERSION" - 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 '"') - 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 '"') + fi - # Create MOTD profile script - local PROFILE_FILE="/etc/profile.d/00_lxc-details.sh" - cat >"$PROFILE_FILE" <"$PROFILE_FILE" </dev/null | awk '{print \$1}' || ip -4 addr show scope global | grep -oP '(?<=inet\s)\\d+(\\.\\d+){3}' | head -1)${CL:-}" +echo -e "${YW:-} IP Address: ${GN:-}\$(hostname -I 2>/dev/null | awk '{print \$1}' || ip -4 addr show scope global | awk '/inet /{print \$2}' | cut -d/ -f1 | head -1)${CL:-}" echo -e "${YW:-} Repository: ${GN:-}https://github.com/community-scripts/ProxmoxVED${CL:-}" echo "" EOF - # Disable default MOTD scripts (Debian/Ubuntu) - [[ -d /etc/update-motd.d ]] && chmod -x /etc/update-motd.d/* 2>/dev/null || true + # Disable default MOTD scripts (Debian/Ubuntu) + [[ -d /etc/update-motd.d ]] && chmod -x /etc/update-motd.d/* 2>/dev/null || true - # Configure SSH root access if requested - if [[ "${SSH_ROOT:-}" == "yes" ]]; then - # Ensure SSH server is installed - if [[ ! -f /etc/ssh/sshd_config ]]; then - msg_info "Installing SSH server" - case "$PKG_MANAGER" in - apt) - pkg_install openssh-server - ;; - apk) - pkg_install openssh - rc-update add sshd default 2>/dev/null || true - ;; - dnf | yum) - pkg_install openssh-server - ;; - zypper) - pkg_install openssh - ;; - emerge) - pkg_install net-misc/openssh - ;; - esac - msg_ok "Installed SSH server" - fi - - local sshd_config="/etc/ssh/sshd_config" - if [[ -f "$sshd_config" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" "$sshd_config" - sed -i "s/PermitRootLogin prohibit-password/PermitRootLogin yes/g" "$sshd_config" - - case "$INIT_SYSTEM" in - systemd) - svc_restart sshd 2>/dev/null || svc_restart ssh 2>/dev/null || true - ;; - openrc) - svc_enable sshd 2>/dev/null || true - svc_start sshd 2>/dev/null || true - ;; - *) - svc_restart sshd 2>/dev/null || true - ;; - esac - fi + # Configure SSH root access if requested + if [[ "${SSH_ROOT:-}" == "yes" ]]; then + # Ensure SSH server is installed + if [[ ! -f /etc/ssh/sshd_config ]]; then + msg_info "Installing SSH server" + case "$PKG_MANAGER" in + apt) + pkg_install openssh-server + ;; + apk) + pkg_install openssh + rc-update add sshd default 2>/dev/null || true + ;; + dnf | yum) + pkg_install openssh-server + ;; + zypper) + pkg_install openssh + ;; + emerge) + pkg_install net-misc/openssh + ;; + esac + msg_ok "Installed SSH server" fi + + local sshd_config="/etc/ssh/sshd_config" + if [[ -f "$sshd_config" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" "$sshd_config" + sed -i "s/PermitRootLogin prohibit-password/PermitRootLogin yes/g" "$sshd_config" + + case "$INIT_SYSTEM" in + systemd) + svc_restart sshd 2>/dev/null || svc_restart ssh 2>/dev/null || true + ;; + openrc) + svc_enable sshd 2>/dev/null || true + svc_start sshd 2>/dev/null || true + ;; + *) + svc_restart sshd 2>/dev/null || true + ;; + esac + fi + fi } # ============================================================================== @@ -845,104 +845,104 @@ EOF # Customizes container for passwordless login and creates update script # ------------------------------------------------------------------------------ customize() { - if [[ "${PASSWORD:-}" == "" ]]; then - msg_info "Customizing Container" + if [[ "${PASSWORD:-}" == "" ]]; then + msg_info "Customizing Container" - # Remove root password for auto-login - passwd -d root &>/dev/null || true + # Remove root password for auto-login + passwd -d root &>/dev/null || true - case "$INIT_SYSTEM" in - systemd) - # Mask services that block boot in LXC containers - # systemd-homed-firstboot.service hangs waiting for user input on Fedora - systemctl mask systemd-homed-firstboot.service &>/dev/null || true - systemctl mask systemd-homed.service &>/dev/null || true + case "$INIT_SYSTEM" in + systemd) + # Mask services that block boot in LXC containers + # systemd-homed-firstboot.service hangs waiting for user input on Fedora + systemctl mask systemd-homed-firstboot.service &>/dev/null || true + systemctl mask systemd-homed.service &>/dev/null || true - # Configure console-getty for auto-login in LXC containers - # console-getty.service is THE service that handles /dev/console in LXC - # It's present on all systemd distros but not enabled by default on Fedora/RHEL + # Configure console-getty for auto-login in LXC containers + # console-getty.service is THE service that handles /dev/console in LXC + # It's present on all systemd distros but not enabled by default on Fedora/RHEL - if [[ -f /usr/lib/systemd/system/console-getty.service ]]; then - mkdir -p /etc/systemd/system/console-getty.service.d - cat >/etc/systemd/system/console-getty.service.d/override.conf <<'EOF' + if [[ -f /usr/lib/systemd/system/console-getty.service ]]; then + mkdir -p /etc/systemd/system/console-getty.service.d + cat >/etc/systemd/system/console-getty.service.d/override.conf <<'EOF' [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud 115200,38400,9600 - $TERM EOF - # Enable console-getty for LXC web console (required on Fedora/RHEL) - systemctl enable console-getty.service &>/dev/null || true - fi + # Enable console-getty for LXC web console (required on Fedora/RHEL) + systemctl enable console-getty.service &>/dev/null || true + fi - # Also configure container-getty@1 (Debian/Ubuntu default in LXC) - if [[ -f /usr/lib/systemd/system/container-getty@.service ]]; then - mkdir -p /etc/systemd/system/container-getty@1.service.d - cat >/etc/systemd/system/container-getty@1.service.d/override.conf <<'EOF' + # Also configure container-getty@1 (Debian/Ubuntu default in LXC) + if [[ -f /usr/lib/systemd/system/container-getty@.service ]]; then + mkdir -p /etc/systemd/system/container-getty@1.service.d + cat >/etc/systemd/system/container-getty@1.service.d/override.conf <<'EOF' [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 - $TERM EOF - fi + fi - # Reload systemd and restart getty services to apply auto-login - systemctl daemon-reload - systemctl restart console-getty.service &>/dev/null || true - systemctl restart container-getty@1.service &>/dev/null || true - ;; + # Reload systemd and restart getty services to apply auto-login + systemctl daemon-reload + systemctl restart console-getty.service &>/dev/null || true + systemctl restart container-getty@1.service &>/dev/null || true + ;; - openrc) - # Alpine/Gentoo: modify inittab for auto-login - if [[ -f /etc/inittab ]]; then - sed -i 's|^tty1::respawn:.*|tty1::respawn:/sbin/agetty --autologin root --noclear tty1 38400 linux|' /etc/inittab - fi - touch /root/.hushlogin - ;; + openrc) + # Alpine/Gentoo: modify inittab for auto-login + if [[ -f /etc/inittab ]]; then + sed -i 's|^tty1::respawn:.*|tty1::respawn:/sbin/agetty --autologin root --noclear tty1 38400 linux|' /etc/inittab + fi + touch /root/.hushlogin + ;; - sysvinit) - # Devuan/older systems - modify inittab for auto-login - # Devuan 5 (daedalus) uses SysVinit with various inittab formats - # CRITICAL: LXC uses /dev/console, NOT tty1! pct console connects to console device - if [[ -f /etc/inittab ]]; then - # Backup original inittab - cp /etc/inittab /etc/inittab.bak 2>/dev/null || true + sysvinit) + # Devuan/older systems - modify inittab for auto-login + # Devuan 5 (daedalus) uses SysVinit with various inittab formats + # CRITICAL: LXC uses /dev/console, NOT tty1! pct console connects to console device + if [[ -f /etc/inittab ]]; then + # Backup original inittab + cp /etc/inittab /etc/inittab.bak 2>/dev/null || true - # First, enable autologin on tty1 (for direct access) - sed -i 's|^1:[0-9]*:respawn:.*/\(a\?getty\).*|1:2345:respawn:/sbin/agetty --autologin root --noclear tty1 38400 linux|' /etc/inittab + # First, enable autologin on tty1 (for direct access) + sed -i 's|^1:[0-9]*:respawn:.*/\(a\?getty\).*|1:2345:respawn:/sbin/agetty --autologin root --noclear tty1 38400 linux|' /etc/inittab - # CRITICAL: Add console entry for LXC - this is what pct console uses! - # Check if there's already a console getty entry - if ! grep -qE '^[^#].*respawn.*console' /etc/inittab; then - # Add new console entry for LXC - echo "" >>/etc/inittab - echo "# LXC console autologin (added by community-scripts)" >>/etc/inittab - echo "co:2345:respawn:/sbin/agetty --autologin root --noclear console 115200,38400,9600 linux" >>/etc/inittab - else - # Enable autologin on existing console entry - sed -i 's|^[^#]*:[0-9]*:respawn:.*/\(a\?getty\).*console.*|co:2345:respawn:/sbin/agetty --autologin root --noclear console 115200,38400,9600 linux|' /etc/inittab - fi + # CRITICAL: Add console entry for LXC - this is what pct console uses! + # Check if there's already a console getty entry + if ! grep -qE '^[^#].*respawn.*console' /etc/inittab; then + # Add new console entry for LXC + echo "" >>/etc/inittab + echo "# LXC console autologin (added by community-scripts)" >>/etc/inittab + echo "co:2345:respawn:/sbin/agetty --autologin root --noclear console 115200,38400,9600 linux" >>/etc/inittab + else + # Enable autologin on existing console entry + sed -i 's|^[^#]*:[0-9]*:respawn:.*/\(a\?getty\).*console.*|co:2345:respawn:/sbin/agetty --autologin root --noclear console 115200,38400,9600 linux|' /etc/inittab + fi - # Force a reload of inittab - try multiple methods - telinit q &>/dev/null || init q &>/dev/null || kill -1 1 &>/dev/null || true - fi - touch /root/.hushlogin - ;; - esac + # Force a reload of inittab - try multiple methods + telinit q &>/dev/null || init q &>/dev/null || kill -1 1 &>/dev/null || true + fi + touch /root/.hushlogin + ;; + esac - msg_ok "Customized Container" - fi + msg_ok "Customized Container" + fi - # Create update script - # Use var_os for OS-based containers, otherwise use app name - local update_script_name="${var_os:-$app}" - echo "bash -c \"\$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/ct/${update_script_name}.sh)\"" >/usr/bin/update - chmod +x /usr/bin/update + # Create update script + # Use var_os for OS-based containers, otherwise use app name + local update_script_name="${var_os:-$app}" + echo "bash -c \"\$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/ct/${update_script_name}.sh)\"" >/usr/bin/update + chmod +x /usr/bin/update - # Inject SSH authorized keys if provided - 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 + # Inject SSH authorized keys if provided + 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 } # ============================================================================== @@ -956,8 +956,8 @@ EOF # Returns: 0 if valid, 1 if invalid # ------------------------------------------------------------------------------ validate_tz() { - local tz="$1" - [[ -f "/usr/share/zoneinfo/$tz" ]] + local tz="$1" + [[ -f "/usr/share/zoneinfo/$tz" ]] } # ------------------------------------------------------------------------------ @@ -966,21 +966,21 @@ validate_tz() { # Sets container timezone # ------------------------------------------------------------------------------ set_timezone() { - local tz="$1" - if validate_tz "$tz"; then - ln -sf "/usr/share/zoneinfo/$tz" /etc/localtime - echo "$tz" >/etc/timezone 2>/dev/null || true + local tz="$1" + if validate_tz "$tz"; then + ln -sf "/usr/share/zoneinfo/$tz" /etc/localtime + echo "$tz" >/etc/timezone 2>/dev/null || true - # Update tzdata if available - case "$PKG_MANAGER" in - apt) - dpkg-reconfigure -f noninteractive tzdata 2>/dev/null || true - ;; - esac - msg_ok "Timezone set to $tz" - else - msg_warn "Invalid timezone: $tz" - fi + # Update tzdata if available + case "$PKG_MANAGER" in + apt) + dpkg-reconfigure -f noninteractive tzdata 2>/dev/null || true + ;; + esac + msg_ok "Timezone set to $tz" + else + msg_warn "Invalid timezone: $tz" + fi } # ------------------------------------------------------------------------------ @@ -989,9 +989,9 @@ set_timezone() { # Prints detected OS information (for debugging) # ------------------------------------------------------------------------------ os_info() { - echo "OS Type: $OS_TYPE" - echo "OS Family: $OS_FAMILY" - echo "OS Version: $OS_VERSION" - echo "Pkg Manager: $PKG_MANAGER" - echo "Init System: $INIT_SYSTEM" + echo "OS Type: $OS_TYPE" + echo "OS Family: $OS_FAMILY" + echo "OS Version: $OS_VERSION" + echo "Pkg Manager: $PKG_MANAGER" + echo "Init System: $INIT_SYSTEM" }