├── LICENSE ├── README.md ├── SECURITY.md ├── linux_general └── ssh │ └── ssh_install.sh └── proxmox ├── apps ├── arr │ └── arr.sh ├── keycloak │ └── keycloak_update.sh ├── komga │ ├── komga_install.sh │ └── komga_update.sh ├── link_warden │ └── linkwarden_install.sh ├── nginx_proxy_manager │ ├── npm_install.sh │ └── npm_plus_install.sh ├── plex │ └── plex_install_hw.sh └── rustdesk │ └── rustdesk_install.sh ├── lxc ├── debian_lxc_git.sh ├── lxc_update_selectable.sh └── ubuntu_lxc_git.sh ├── pve_update.sh └── ultra_scripts ├── enhanced_vm_lxc_install.sh ├── temp.sh └── vm_lxc_install.sh /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # technaut_scripts :: 2 | 3 | Proxmox scripts designed to be run as a standalone script. Just run through the customizable script and done. 4 | You can run the app install scripts as standlone as well. Keep reading to learn more! 5 | 6 | The scripts are open and available for review, everything is as simple as they need to be. I try to make comments on every section within a code block, in order to make it easier to follow for less technical users. 7 | These are very much in early development, and I am not responsible for anything breaking. Use at your own risk! 8 | 9 | ## Basic Run Commands 10 | Run LXC or VM Creation with: ```bash -c "$(wget -qLO - https://git.technaut.io)"``` 11 | 12 | Run Install scripts alone with: ```wget -qO- "https://git.technaut.io | bash -s -- ``` 13 | 14 | 15 | ## Currently Available: 16 | 17 | ### Installs: 18 | Run these to make a highly customizable vm/lxc on Proxmox. 19 | 20 | #### AllInstaller: 21 | ``` 22 | https://raw.githubusercontent.com/cindustriesio/technaut_scripts/refs/heads/main/proxmox/ultra_scripts/enhanced_vm_lxc_install.sh 23 | ``` 24 | 25 | #### Debian: 26 | ``` 27 | bash -c "$(wget -qLO - https://raw.githubusercontent.com/cindustriesio/technaut_scripts/refs/heads/main/proxmox/lxc/debian_lxc_git.sh)" 28 | ``` 29 | 30 | #### Ubuntu: 31 | ``` 32 | bash -c "$(wget -qLO - https://raw.githubusercontent.com/cindustriesio/technaut_scripts/refs/heads/main/proxmox/lxc/ubuntu_lxc_git.sh)" 33 | ``` 34 | 35 | You can inject whatever script at the end to install applications into the newly created LXC. Just copy paste the github install script into it. 36 | 37 | I have a few available in this repository```https://github.com/cindustriesio/technaut_scripts/proxmox/apps``` for testing. 38 | 39 | ### LXC update: 40 | This an update script to select multiple LXCs at once for updating. 41 | ``` 42 | bash -c "$(wget -qLO - https://raw.githubusercontent.com/cindustriesio/technaut_scripts/refs/heads/main/proxmox/lxc/lxc_update_selectable.sh)" 43 | ``` 44 | 45 | Any questions or comments just ask! I am new to git and coding in general, and this is a learning experience while trying to help the community. 46 | 47 | ## technaut_apps :: 48 | If you are intrested in some other projects, check out [lonewolf_apps](https://github.com/cindustriesio/lonewolf_apps). 49 | I am curently working on a few encryption :closed_lock_with_key: apps, will be publishing some in the new future so be sure to save for later! 50 | 51 | #### :: Contribute :: 52 | I welcome more contributors, this is becoming a large scope project... 53 | If you want to help out with alternative methods, consider a [donation](https://ko-fi.com/technaut951)! I work on these when I have time, so updates will come out sproadically. 54 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Supported Versions 2 | This project currently supports the following versions of Proxmox VE: 3 | 4 | | Version | Supported | 5 | | ------- | ------------------ | 6 | | 8.3.x | :white_check_mark: | 7 | 8 | 9 | ## Reporting a Vulnerability 10 | 11 | Security vulnerabilities shouldn’t be reported publicly to prevent potential exploitation. Instead, please report any vulnerabilities privately by reaching out directly to myself. 12 | 13 | If you have any questions or concerns about this security policy, please don't hesitate reach out. 14 | -------------------------------------------------------------------------------- /linux_general/ssh/ssh_install.sh: -------------------------------------------------------------------------------- 1 | # !/bin/bash 2 | # Description: This script will install and enable ssh on the system 3 | # Version: 0.1 4 | # Created by: Clark Industries IO 5 | 6 | # below command will Update package lists 7 | sudo apt update 8 | 9 | # below command will Upgrade the packages that can be upgraded 10 | sudo apt upgrade -y 11 | 12 | #install and enable ssh 13 | sudo apt install openssh-server openssh-client -y 14 | 15 | #add ssh to launch on system boot 16 | sudo systemctl enable ssh 17 | 18 | #allow SSH in firewall 19 | sudo ufw allow ssh 20 | 21 | # below command will Remove unnecessary packages and dependencies for good memory management 22 | sudo apt autoremove -y 23 | 24 | # below command will Clean package cache 25 | sudo apt clean -y 26 | 27 | # below command will Display system update status on terminal to know if the update and upgrade is successfull 28 | echo "System updates and upgrades completed successfully." -------------------------------------------------------------------------------- /proxmox/apps/arr/arr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Description: Arrr in a Proxmox LXC container 3 | # Version: .1 4 | # ProjectL: Lonewolf Scripts 5 | # Created by: Clark Industries IO 6 | 7 | # Default settings 8 | MEDIA_DIR="/mnt/media" 9 | DOCKER_NETWORK="arr_network" 10 | VPN_CONTAINER="" 11 | LOG_FILE="/var/log/arr_install.log" 12 | 13 | # Ensure log file exists 14 | touch "$LOG_FILE" 15 | 16 | log() { 17 | echo "$(date +"%Y-%m-%d %H:%M:%S") - $1" | tee -a "$LOG_FILE" 18 | } 19 | 20 | # Install Docker if not installed 21 | install_docker() { 22 | if ! command -v docker &> /dev/null; then 23 | log "Docker not found. Installing..." 24 | apt-get update && apt-get install -y \ 25 | ca-certificates curl gnupg lsb-release apt-transport-https software-properties-common 26 | curl -fsSL https://download.docker.com/linux/debian/gpg | tee /etc/apt/keyrings/docker.asc > /dev/null 27 | chmod a+r /etc/apt/keyrings/docker.asc 28 | echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null 29 | apt-get update && apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin 30 | systemctl enable --now docker 31 | fi 32 | } 33 | 34 | # Ensure whiptail is installed 35 | if ! command -v whiptail &> /dev/null; then 36 | log "whiptail not found. Installing..." 37 | apt-get update && apt-get install -y whiptail 38 | fi 39 | 40 | # Ensure Docker network exists 41 | setup_network() { 42 | if ! docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then 43 | docker network create "$DOCKER_NETWORK" 44 | log "Created Docker network: $DOCKER_NETWORK" 45 | fi 46 | } 47 | 48 | # Prompt for storage location 49 | setup_storage() { 50 | MEDIA_DIR=$(whiptail --inputbox "Enter media storage directory (default: $MEDIA_DIR)" 10 60 "$MEDIA_DIR" 3>&1 1>&2 2>&3) 51 | mkdir -p "$MEDIA_DIR" 52 | log "Media directory set to: $MEDIA_DIR" 53 | } 54 | 55 | # Prompt for VPN container 56 | setup_vpn() { 57 | VPN_CONTAINER=$(whiptail --inputbox "Enter VPN container name (leave empty for none)" 10 60 "" 3>&1 1>&2 2>&3) 58 | if [ -n "$VPN_CONTAINER" ]; then 59 | log "Using VPN container: $VPN_CONTAINER" 60 | else 61 | log "No VPN container selected." 62 | fi 63 | } 64 | 65 | # Install selected *arr apps 66 | install_arr_app() { 67 | local app_name=$1 68 | local container_name=$2 69 | local image_name=$3 70 | local port=$4 71 | 72 | log "Installing $app_name..." 73 | 74 | docker run -d \ 75 | --name "$container_name" \ 76 | --network="$DOCKER_NETWORK" \ 77 | -p "$port:$port" \ 78 | -v "$MEDIA_DIR:/media" \ 79 | ${VPN_CONTAINER:+--network container:$VPN_CONTAINER} \ 80 | --restart unless-stopped \ 81 | "$image_name" &>> "$LOG_FILE" 82 | 83 | if [ $? -eq 0 ]; then 84 | log "$app_name installed successfully." 85 | else 86 | log "Failed to install $app_name. Check $LOG_FILE for details." 87 | fi 88 | } 89 | 90 | # Select apps 91 | select_apps() { 92 | OPTIONS=( 93 | "sonarr" "Sonarr" OFF 94 | "radarr" "Radarr" OFF 95 | "lidarr" "Lidarr" OFF 96 | "prowlarr" "Prowlarr" OFF 97 | "readarr" "Readarr" OFF 98 | "bazarr" "Bazarr" OFF 99 | "whisparr" "Whisparr" OFF 100 | "qbittorrent" "Qbittorrent" OFF 101 | "jackett" "Jackett" OFF 102 | "mylar3" "Mylar3" OFF 103 | "transmission" "Transmission" OFF 104 | "deluge" "Deluge" OFF 105 | "flexget" "Flexget" OFF 106 | "lazylibrarian" "LazyLibrarian" OFF 107 | "medusa" "Medusa" OFF 108 | "couchpotato" "CouchPotato" OFF 109 | "tautulli" "Tautulli" OFF 110 | "ombi" "Ombi" OFF 111 | "filebot" "FileBot" OFF 112 | ) 113 | 114 | SELECTED=$(whiptail --checklist "Select *arr apps to install:" 25 80 15 "${OPTIONS[@]}" 3>&1 1>&2 2>&3) 115 | 116 | if [ -z "$SELECTED" ]; then 117 | log "No apps selected. Exiting..." 118 | exit 0 119 | fi 120 | 121 | for app in $SELECTED; do 122 | case $app in 123 | "sonarr") install_arr_app "Sonarr" "sonarr" "lscr.io/linuxserver/sonarr" 8989 ;; 124 | "radarr") install_arr_app "Radarr" "radarr" "lscr.io/linuxserver/radarr" 7878 ;; 125 | "lidarr") install_arr_app "Lidarr" "lidarr" "lscr.io/linuxserver/lidarr" 8686 ;; 126 | "prowlarr") install_arr_app "Prowlarr" "prowlarr" "lscr.io/linuxserver/prowlarr" 9696 ;; 127 | "readarr") install_arr_app "Readarr" "readarr" "lscr.io/linuxserver/readarr" 8787 ;; 128 | "bazarr") install_arr_app "Bazarr" "bazarr" "lscr.io/linuxserver/bazarr" 6767 ;; 129 | "whisparr") install_arr_app "Whisparr" "whisparr" "lscr.io/linuxserver/whisparr" 8181 ;; 130 | "qbittorrent") install_arr_app "Qbittorrent" "qbittorrent" "lscr.io/linuxserver/qbittorrent" 8080 ;; 131 | "jackett") install_arr_app "Jackett" "jackett" "lscr.io/linuxserver/jackett" 9117 ;; 132 | "mylar3") install_arr_app "Mylar3" "mylar3" "lscr.io/linuxserver/mylar3" 8090 ;; 133 | "transmission") install_arr_app "Transmission" "transmission" "lscr.io/linuxserver/transmission" 9091 ;; 134 | "deluge") install_arr_app "Deluge" "deluge" "lscr.io/linuxserver/deluge" 8112 ;; 135 | "flexget") install_arr_app "Flexget" "flexget" "flexget/flexget" 5050 ;; 136 | "lazylibrarian") install_arr_app "LazyLibrarian" "lazylibrarian" "lscr.io/linuxserver/lazylibrarian" 5299 ;; 137 | "medusa") install_arr_app "Medusa" "medusa" "lscr.io/linuxserver/medusa" 8081 ;; 138 | "couchpotato") install_arr_app "CouchPotato" "couchpotato" "lscr.io/linuxserver/couchpotato" 5050 ;; 139 | "tautulli") install_arr_app "Tautulli" "tautulli" "lscr.io/linuxserver/tautulli" 8181 ;; 140 | "ombi") install_arr_app "Ombi" "ombi" "lscr.io/linuxserver/ombi" 5000 ;; 141 | "filebot") install_arr_app "FileBot" "filebot" "lscr.io/linuxserver/filebot" 8080 ;; 142 | esac 143 | done 144 | } 145 | 146 | # Main execution 147 | log "Starting *arr installation..." 148 | install_docker 149 | setup_storage 150 | setup_network 151 | setup_vpn 152 | select_apps 153 | log "Installation complete!" 154 | -------------------------------------------------------------------------------- /proxmox/apps/keycloak/keycloak_update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Description: Update Keycloak to the latest version 3 | # Version: 1.0 4 | # Created by: Clark Industries IO 5 | 6 | # Set variables 7 | KEYCLOAK_DIR="/opt/keycloak" 8 | BACKUP_DIR="/root/keycloak_backup_$(date +%Y%m%d_%H%M%S)" 9 | LATEST_VERSION=$(curl -s https://api.github.com/repos/keycloak/keycloak/releases/latest | jq -r '.tag_name') 10 | 11 | # Stop Keycloak service 12 | echo "Stopping Keycloak..." 13 | systemctl stop keycloak 14 | 15 | # Backup current Keycloak installation 16 | echo "Backing up existing Keycloak to $BACKUP_DIR..." 17 | mkdir -p "$BACKUP_DIR" 18 | cp -r "$KEYCLOAK_DIR" "$BACKUP_DIR" 19 | 20 | # Download latest Keycloak release 21 | echo "Downloading Keycloak $LATEST_VERSION..." 22 | cd /opt 23 | wget -q wget "https://github.com/keycloak/keycloak/releases/download/$LATEST_VERSION/keycloak-$LATEST_VERSION.tar.gz" 24 | unzip -q "keycloak-$LATEST_VERSION.zip" 25 | mv "keycloak-$LATEST_VERSION" keycloak-new 26 | rm "keycloak-$LATEST_VERSION.zip" 27 | 28 | # Copy old configurations 29 | echo "Copying configuration files..." 30 | cp -r "$KEYCLOAK_DIR/conf" "keycloak-new/" 31 | cp -r "$KEYCLOAK_DIR/data" "keycloak-new/" 32 | cp -r "$KEYCLOAK_DIR/themes" "keycloak-new/" 33 | cp -r "$KEYCLOAK_DIR/providers" "keycloak-new/" 34 | 35 | # Apply database migrations Comment out unless needed! 36 | #echo "Running database migrations..." 37 | #/opt/keycloak-new/bin/kc.sh start --optimized --auto-build 38 | 39 | # Replace old Keycloak version 40 | echo "Replacing old Keycloak version..." 41 | mv "$KEYCLOAK_DIR" "${KEYCLOAK_DIR}_old" 42 | mv "keycloak-new" "$KEYCLOAK_DIR" 43 | 44 | # Restart Keycloak 45 | echo "Restarting Keycloak..." 46 | systemctl start keycloak 47 | 48 | # Clean up old files 49 | echo "Cleaning up old files..." 50 | rm -rf "${KEYCLOAK_DIR}_old" 51 | 52 | echo "Keycloak successfully updated to $LATEST_VERSION!" 53 | -------------------------------------------------------------------------------- /proxmox/apps/komga/komga_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Description: Update Komga in a Proxmox LXC container 3 | # Version: .1 4 | # ProjectL: Lonewolf Scripts 5 | # Created by: Clark Industries IO 6 | 7 | set -e 8 | 9 | # LXC Configuration 10 | CTID="$1" # LXC Container ID 11 | 12 | # Ensure LXC ID is provided 13 | if [[ -z "$CTID" ]]; then 14 | echo "[ERROR] Usage: $0 " 15 | exit 1 16 | fi 17 | 18 | # Ensure the LXC exists 19 | if ! pct list | grep -q "^ *$CTID"; then 20 | echo "[ERROR] LXC $CTID does not exist. Please create it first." 21 | exit 1 22 | fi 23 | 24 | # Prompt for media location 25 | read -rp "Enter the path for media storage (e.g., /mnt/media): " MEDIA_PATH 26 | 27 | # Run commands inside LXC 28 | pct exec $CTID -- bash -c " 29 | apt update && apt install -y curl docker.io docker-compose ufw && \ 30 | systemctl enable --now docker && \ 31 | ufw allow 25600/tcp && \ 32 | mkdir -p /opt/komga \"$MEDIA_PATH\" && \ 33 | cat > /opt/komga/docker-compose.yml <<"EOF" 34 | version: '3.3' 35 | services: 36 | komga: 37 | image: gotson/komga:latest 38 | container_name: komga 39 | restart: unless-stopped 40 | ports: 41 | - \"25600:25600\" 42 | volumes: 43 | - /opt/komga/config:/config 44 | - \"$MEDIA_PATH\":/books 45 | EOF 46 | docker-compose -f /opt/komga/docker-compose.yml up -d 47 | " 48 | 49 | echo "Komga Docker installation in LXC $CTID completed successfully with media storage at $MEDIA_PATH!" 50 | -------------------------------------------------------------------------------- /proxmox/apps/komga/komga_update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Description: Update Komga in a Proxmox LXC container 3 | # Version: .1 4 | # ProjectL: Lonewolf Scripts 5 | # Created by: Clark Industries IO 6 | 7 | # Configuration 8 | CTID="$1" # Container ID passed as an argument 9 | CONF_FILE="/etc/pve/lxc/${CTID}.conf" 10 | 11 | # Logging Functions 12 | msg_info() { 13 | echo -e "\e[1;34m[INFO]\e[0m $1" 14 | } 15 | msg_ok() { 16 | echo -e "\e[1;32m[OK]\e[0m $1" 17 | } 18 | msg_error() { 19 | echo -e "\e[1;31m[ERROR]\e[0m $1" 20 | } 21 | 22 | # Ensure CTID is provided 23 | if [[ -z "$CTID" ]]; then 24 | msg_error "Usage: $0 " 25 | exit 1 26 | fi 27 | 28 | # Ensure the LXC container exists 29 | if [[ ! -f "$CONF_FILE" ]]; then 30 | msg_error "LXC container with ID $CTID not found!" 31 | exit 1 32 | fi 33 | 34 | msg_info "Updating Komga in LXC $CTID..." 35 | 36 | msg_info "Stopping Komga container..." 37 | pct exec "$CTID" -- bash -c "cd /opt/komga && docker-compose down" 38 | 39 | msg_info "Pulling latest Komga image..." 40 | pct exec "$CTID" -- bash -c "docker pull gotson/komga:latest" 41 | 42 | msg_info "Starting Komga container..." 43 | pct exec "$CTID" -- bash -c "cd /opt/komga && docker-compose up -d" 44 | 45 | msg_info "Removing old unused Docker images..." 46 | pct exec "$CTID" -- bash -c "docker image prune -f" 47 | 48 | msg_ok "Komga has been updated successfully!" 49 | msg_info "Access it at http://:25600" 50 | -------------------------------------------------------------------------------- /proxmox/apps/link_warden/linkwarden_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Description: Proxmox install for LinkWarden 3 | # Version: .1 4 | # ProjectL: Lonewolf Scripts 5 | # Created by: Clark Industries IO 6 | 7 | set -e 8 | 9 | # LXC Configuration 10 | LXC_ID="$1" # LXC Container ID 11 | 12 | # Ensure LXC ID is provided 13 | if [[ -z "$LXC_ID" ]]; then 14 | echo "[ERROR] Usage: $0 " 15 | exit 1 16 | fi 17 | 18 | # Ensure the LXC exists 19 | if ! pct list | grep -q "^ *$LXC_ID"; then 20 | echo "[ERROR] LXC $LXC_ID does not exist. Please create it first." 21 | exit 1 22 | fi 23 | 24 | # Run commands inside LXC 25 | pct exec $LXC_ID -- bash -c " 26 | apt update && apt install -y curl docker.io docker-compose ufw && \ 27 | systemctl enable --now docker && \ 28 | ufw allow 3000/tcp && \ 29 | mkdir -p /opt/linkwarden && \ 30 | cat > /opt/linkwarden/docker-compose.yml <<"EOF" 31 | version: '3.3' 32 | services: 33 | linkwarden: 34 | image: ghcr.io/linkwarden/linkwarden:latest 35 | container_name: linkwarden 36 | restart: unless-stopped 37 | ports: 38 | - \"3000:3000\" 39 | volumes: 40 | - /opt/linkwarden/data:/data 41 | EOF 42 | docker-compose -f /opt/linkwarden/docker-compose.yml up -d 43 | " 44 | 45 | echo "Linkwarden installation in LXC $LXC_ID completed successfully with data stored in /opt/linkwarden!" 46 | -------------------------------------------------------------------------------- /proxmox/apps/nginx_proxy_manager/npm_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Description: Proxmox install for Nginx Proxy Manager 3 | # Version: .1 4 | # ProjectL: Lonewolf Scripts 5 | # Created by: Clark Industries IO 6 | 7 | # Configuration 8 | CTID="$1" # Container ID passed as an argument 9 | CONF_FILE="/etc/pve/lxc/${CTID}.conf" 10 | 11 | # Logging Functions 12 | msg_info() { 13 | echo -e "\e[1;34m[INFO]\e[0m $1" 14 | } 15 | msg_ok() { 16 | echo -e "\e[1;32m[OK]\e[0m $1" 17 | } 18 | msg_error() { 19 | echo -e "\e[1;31m[ERROR]\e[0m $1" 20 | } 21 | 22 | # Ensure CTID is provided 23 | if [[ -z "$CTID" ]]; then 24 | msg_error "Usage: $0 " 25 | exit 1 26 | fi 27 | 28 | # Ensure the LXC container exists 29 | if [[ ! -f "$CONF_FILE" ]]; then 30 | msg_error "LXC container with ID $CTID not found!" 31 | exit 1 32 | fi 33 | 34 | # Generate random passwords 35 | DB_ROOT_PASS=$(openssl rand -base64 24) 36 | DB_USER_PASS=$(openssl rand -base64 24) 37 | 38 | msg_info "Generated secure database credentials." 39 | 40 | msg_info "Updating Container..." 41 | pct exec "$CTID" -- bash -c "apt update && apt upgrade -y" 42 | 43 | msg_info "Installing Dependencies..." 44 | pct exec "$CTID" -- bash -c "apt install -y curl wget gnupg software-properties-common" 45 | 46 | msg_info "Installing Docker & Docker-Compose..." 47 | pct exec "$CTID" -- bash -c "apt install -y docker.io docker-compose" 48 | pct exec "$CTID" -- bash -c "systemctl enable --now docker" 49 | 50 | msg_info "Creating Nginx Proxy Manager Directory..." 51 | pct exec "$CTID" -- bash -c "mkdir -p /opt/npm && cd /opt/npm" 52 | 53 | msg_info "Setting Up Docker-Compose File..." 54 | pct exec "$CTID" -- bash -c "cat < /opt/npm/docker-compose.yml 55 | version: '3' 56 | services: 57 | app: 58 | image: 'jc21/nginx-proxy-manager:latest' 59 | restart: unless-stopped 60 | ports: 61 | - '80:80' 62 | - '81:81' 63 | - '443:443' 64 | environment: 65 | DB_MYSQL_HOST: 'db' 66 | DB_MYSQL_PORT: '3306' 67 | DB_MYSQL_USER: 'npm' 68 | DB_MYSQL_PASSWORD: '$DB_USER_PASS' 69 | DB_MYSQL_NAME: 'npm' 70 | volumes: 71 | - ./data:/data 72 | - ./letsencrypt:/etc/letsencrypt 73 | 74 | db: 75 | image: 'mysql:5.7' 76 | restart: unless-stopped 77 | environment: 78 | MYSQL_ROOT_PASSWORD: '$DB_ROOT_PASS' 79 | MYSQL_DATABASE: 'npm' 80 | MYSQL_USER: 'npm' 81 | MYSQL_PASSWORD: '$DB_USER_PASS' 82 | volumes: 83 | - ./mysql:/var/lib/mysql 84 | EOF" 85 | 86 | msg_info "Starting Nginx Proxy Manager..." 87 | pct exec "$CTID" -- bash -c "cd /opt/npm && docker-compose up -d" 88 | 89 | msg_info "Storing Credentials in /root/npm_credentials.txt..." 90 | pct exec "$CTID" -- bash -c "cat < /root/npm_credentials.txt 91 | Nginx Proxy Manager Credentials: 92 | -------------------------------- 93 | Admin Login: http://\$(hostname -I | awk '{print $1}'):81 94 | Default Email: admin@example.com 95 | Default Password: changeme 96 | 97 | Database Credentials: 98 | --------------------- 99 | MySQL Root Password: $DB_ROOT_PASS 100 | MySQL User: npm 101 | MySQL User Password: $DB_USER_PASS 102 | 103 | These credentials were auto-generated. 104 | Change them if necessary. 105 | EOF" 106 | 107 | pct exec "$CTID" -- bash -c "chmod 600 /root/npm_credentials.txt" 108 | 109 | msg_ok "Nginx Proxy Manager Installation Complete!" 110 | msg_info "You can access NPM at http://:81" 111 | msg_info "Default Login: admin@example.com / changeme" 112 | msg_info "Database credentials are stored in /root/npm_credentials.txt" 113 | 114 | -------------------------------------------------------------------------------- /proxmox/apps/nginx_proxy_manager/npm_plus_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Description: Proxmox install for NPMplus 3 | # Version: .1 4 | # ProjectL: Lonewolf Scripts 5 | # Created by: Clark Industries IO 6 | 7 | # Configuration 8 | CTID="$1" # Container ID passed as an argument 9 | CONF_FILE="/etc/pve/lxc/${CTID}.conf" 10 | 11 | # Logging Functions 12 | msg_info() { 13 | echo -e "\e[1;34m[INFO]\e[0m $1" 14 | } 15 | msg_ok() { 16 | echo -e "\e[1;32m[OK]\e[0m $1" 17 | } 18 | msg_error() { 19 | echo -e "\e[1;31m[ERROR]\e[0m $1" 20 | } 21 | 22 | # Ensure CTID is provided 23 | if [[ -z "$CTID" ]]; then 24 | msg_error "Usage: $0 " 25 | exit 1 26 | fi 27 | 28 | # Ensure the LXC container exists 29 | if [[ ! -f "$CONF_FILE" ]]; then 30 | msg_error "LXC container with ID $CTID not found!" 31 | exit 1 32 | fi 33 | 34 | # Generate random passwords 35 | DB_ROOT_PASS=$(openssl rand -base64 24) 36 | DB_USER_PASS=$(openssl rand -base64 24) 37 | 38 | msg_info "Generated secure database credentials." 39 | 40 | msg_info "Updating Container..." 41 | pct exec "$CTID" -- bash -c "apt update && apt upgrade -y" 42 | 43 | msg_info "Installing Dependencies..." 44 | pct exec "$CTID" -- bash -c "apt install -y curl wget gnupg software-properties-common" 45 | 46 | msg_info "Installing Docker & Docker-Compose..." 47 | pct exec "$CTID" -- bash -c "apt install -y docker.io docker-compose" 48 | pct exec "$CTID" -- bash -c "systemctl enable --now docker" 49 | 50 | msg_info "Creating NPMplus Directory..." 51 | pct exec "$CTID" -- bash -c "mkdir -p /opt/npmplus && cd /opt/npmplus" 52 | 53 | msg_info "Setting Up Docker-Compose File..." 54 | pct exec "$CTID" -- bash -c "cat <<"EOF" > /opt/npmplus/docker-compose.yml 55 | version: '3' 56 | services: 57 | app: 58 | image: 'ghcr.io/zoeyvid/npmplus:latest' 59 | restart: unless-stopped 60 | ports: 61 | - '80:80' 62 | - '81:81' 63 | - '443:443' 64 | environment: 65 | DB_MYSQL_HOST: 'db' 66 | DB_MYSQL_PORT: '3306' 67 | DB_MYSQL_USER: 'npm' 68 | DB_MYSQL_PASSWORD: '$DB_USER_PASS' 69 | DB_MYSQL_NAME: 'npm' 70 | volumes: 71 | - ./data:/data 72 | - ./letsencrypt:/etc/letsencrypt 73 | 74 | db: 75 | image: 'mysql:8' 76 | restart: unless-stopped 77 | environment: 78 | MYSQL_ROOT_PASSWORD: '$DB_ROOT_PASS' 79 | MYSQL_DATABASE: 'npm' 80 | MYSQL_USER: 'npm' 81 | MYSQL_PASSWORD: '$DB_USER_PASS' 82 | volumes: 83 | - ./mysql:/var/lib/mysql 84 | EOF" 85 | 86 | msg_info "Starting NPMplus..." 87 | pct exec "$CTID" -- bash -c "cd /opt/npmplus && docker-compose up -d" 88 | 89 | msg_info "Storing Credentials in /root/npmplus_credentials.txt..." 90 | pct exec "$CTID" -- bash -c "cat < /root/npmplus_credentials.txt 91 | NPMplus Installation Info: 92 | -------------------------- 93 | Admin Login: http://\$(hostname -I | awk '{print $1}'):81 94 | Default Email: admin@example.com 95 | Default Password: changeme 96 | 97 | Database Credentials: 98 | --------------------- 99 | MySQL Root Password: $DB_ROOT_PASS 100 | MySQL User: npm 101 | MySQL User Password: $DB_USER_PASS 102 | 103 | These credentials were auto-generated. 104 | Change them if necessary. 105 | EOF" 106 | 107 | pct exec "$CTID" -- bash -c "chmod 600 /root/npmplus_credentials.txt" 108 | 109 | msg_ok "NPMplus Installation Complete!" 110 | msg_info "You can access NPMplus at http://:81" 111 | msg_info "Default Login: admin@example.com / changeme" 112 | msg_info "Database credentials are stored in /root/npmplus_credentials.txt" 113 | -------------------------------------------------------------------------------- /proxmox/apps/plex/plex_install_hw.sh: -------------------------------------------------------------------------------- 1 | # !/bin/bash 2 | # Description: Plex Media Server Installation Script with Hardware Acceleration 3 | # Supported GPUs: Intel (Quick Sync), AMD (VA-API), NVIDIA (NVENC) 4 | # Config: Plex will be configured to use hardware acceleration for transcoding. 5 | # Config: Plex will be installed in a privileged LXC container. 6 | # Tested: Proxmox VE 8.0+ (Bookworm) 7 | # Version: 1.0 8 | # Created by: Clark Industries IO 9 | 10 | # Check if whiptail is installed 11 | if ! command -v whiptail &> /dev/null; then 12 | echo "Whiptail is required but not installed. Install it using: apt-get install whiptail" 13 | exit 1 14 | fi 15 | 16 | # Configuration 17 | CTID="$1" # Container ID passed as an argument 18 | CONF_FILE="/etc/pve/lxc/${CTID}.conf" 19 | 20 | # Logging Functions 21 | msg_info() { 22 | echo -e "\e[1;34m[INFO]\e[0m $1" 23 | } 24 | msg_ok() { 25 | echo -e "\e[1;32m[OK]\e[0m $1" 26 | } 27 | msg_error() { 28 | echo -e "\e[1;31m[ERROR]\e[0m $1" 29 | } 30 | 31 | # Ensure CTID is provided 32 | if [[ -z "$CTID" ]]; then 33 | msg_error "Usage: $0 " 34 | exit 1 35 | fi 36 | 37 | # Ensure the LXC container exists 38 | if [[ ! -f "$CONF_FILE" ]]; then 39 | msg_error "LXC container with ID $CTID not found!" 40 | exit 1 41 | fi 42 | 43 | # Check if user still wants to install app 44 | whiptail --title "Confirm Install" --yesno "Confirm you wish to install Plex in $CTID?" 15 50 45 | if [ $? -ne 0 ]; then 46 | echo "Aborted." 47 | exit 1 48 | fi 49 | 50 | msg_info "Detecting GPU Type..." 51 | 52 | GPU_TYPE="" 53 | if lspci | grep -i 'vga\|display' | grep -iq intel; then 54 | GPU_TYPE="intel" 55 | elif lspci | grep -i 'vga\|display' | grep -iq amd; then 56 | GPU_TYPE="amd" 57 | elif lspci | grep -i 'vga\|display' | grep -iq nvidia; then 58 | GPU_TYPE="nvidia" 59 | else 60 | msg_error "No compatible GPU found! Exiting..." 61 | exit 1 62 | fi 63 | msg_ok "Detected $GPU_TYPE GPU." 64 | 65 | msg_info "Configuring GPU Passthrough for LXC Container $CTID..." 66 | 67 | # Backup existing config 68 | cp "$CONF_FILE" "${CONF_FILE}.backup" 69 | 70 | # Ensure it's a privileged container 71 | if ! grep -q "unprivileged=1" "$CONF_FILE"; then 72 | case "$GPU_TYPE" in 73 | intel|amd) 74 | echo -e "\nlxc.cgroup2.devices.allow = c 226:* rwm" >> "$CONF_FILE" 75 | echo "lxc.mount.entry = /dev/dri dev/dri none bind,optional,create=dir" >> "$CONF_FILE" 76 | msg_ok "Passthrough added for Intel/AMD (VA-API)." 77 | ;; 78 | nvidia) 79 | echo -e "\nlxc.cgroup2.devices.allow = c 195:* rwm" >> "$CONF_FILE" 80 | echo "lxc.mount.entry = /dev/nvidia0 dev/nvidia0 none bind,optional,create=file" >> "$CONF_FILE" 81 | echo "lxc.mount.entry = /dev/nvidiactl dev/nvidiactl none bind,optional,create=file" >> "$CONF_FILE" 82 | echo "lxc.mount.entry = /dev/nvidia-modeset dev/nvidia-modeset none bind,optional,create=file" >> "$CONF_FILE" 83 | msg_ok "Passthrough added for NVIDIA (NVENC)." 84 | ;; 85 | esac 86 | else 87 | msg_error "Unprivileged container detected! GPU passthrough requires a privileged LXC." 88 | exit 1 89 | fi 90 | 91 | msg_info "Restarting LXC Container to Apply Changes..." 92 | pct stop "$CTID" 93 | pct start "$CTID" 94 | msg_ok "GPU Passthrough Setup Complete!" 95 | 96 | # Wait for LXC to boot up 97 | sleep 5 98 | 99 | msg_info "Updating Container..." 100 | pct exec "$CTID" -- bash -c "apt update && apt upgrade -y" 101 | 102 | msg_info "Installing Dependencies..." 103 | pct exec "$CTID" -- bash -c "apt install -y curl wget gnupg software-properties-common" 104 | 105 | msg_info "Adding Plex Repository..." 106 | pct exec "$CTID" -- bash -c "curl https://downloads.plex.tv/plex-keys/PlexSign.key | gpg --dearmor -o /usr/share/keyrings/plex.gpg" 107 | pct exec "$CTID" -- bash -c "echo 'deb [signed-by=/usr/share/keyrings/plex.gpg] https://downloads.plex.tv/repo/deb public main' | tee /etc/apt/sources.list.d/plexmediaserver.list" 108 | 109 | msg_info "Installing Plex Media Server..." 110 | pct exec "$CTID" -- bash -c "apt update && apt install -y plexmediaserver" 111 | 112 | msg_info "Enabling Plex Service..." 113 | pct exec "$CTID" -- bash -c "systemctl enable --now plexmediaserver" 114 | 115 | msg_info "Setting Up Hardware Acceleration..." 116 | pct exec "$CTID" -- bash -c "apt-get -y install va-driver-all ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools" 117 | 118 | msg_info "Configuring GPU Permissions Inside LXC..." 119 | pct exec "$CTID" -- bash -c "chgrp video /dev/dri && chmod 755 /dev/dri && chmod 660 /dev/dri/*" 120 | pct exec "$CTID" -- bash -c "adduser plex video && adduser plex render" 121 | 122 | msg_ok "Hardware Acceleration Setup Complete!" 123 | 124 | # GPU-Specific Packages 125 | case "$GPU_TYPE" in 126 | intel) 127 | msg_info "Installing Intel GPU Drivers..." 128 | pct exec "$CTID" -- bash -c "apt install -y intel-media-va-driver" 129 | msg_ok "Intel Quick Sync Enabled." 130 | ;; 131 | amd) 132 | msg_info "Installing AMD VA-API Drivers..." 133 | pct exec "$CTID" -- bash -c "apt install -y mesa-va-drivers libva-drm2 libva-x11-2" 134 | msg_ok "AMD VA-API Enabled." 135 | ;; 136 | nvidia) 137 | msg_info "Installing NVIDIA VAAPI Driver..." 138 | pct exec "$CTID" -- bash -c "apt install -y nvidia-vaapi-driver" 139 | msg_ok "NVIDIA NVENC Enabled." 140 | ;; 141 | esac 142 | 143 | msg_info "Restarting Plex to Apply Changes..." 144 | pct exec "$CTID" -- bash -c "systemctl restart plexmediaserver" 145 | msg_ok "Plex Installation and GPU Setup Complete!" -------------------------------------------------------------------------------- /proxmox/apps/rustdesk/rustdesk_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Description: Proxmox install for RustDesk 3 | # Version: .1 4 | # ProjectL: Lonewolf Scripts 5 | # Created by: Clark Industries IO 6 | 7 | set -e 8 | 9 | # LXC Configuration 10 | LXC_ID="$1" # LXC Container ID 11 | 12 | # Ensure LXC ID is provided 13 | if [[ -z "$LXC_ID" ]]; then 14 | echo "[ERROR] Usage: $0 " 15 | exit 1 16 | fi 17 | 18 | # Ensure the LXC exists 19 | if ! pct list | grep -q "^ *$LXC_ID"; then 20 | echo "[ERROR] LXC $LXC_ID does not exist. Please create it first." 21 | exit 1 22 | fi 23 | 24 | # Run commands inside LXC 25 | pct exec $LXC_ID -- bash -c " 26 | apt update && apt install -y curl docker.io docker-compose ufw && \ 27 | systemctl enable --now docker && \ 28 | ufw allow 21115/tcp && \ 29 | ufw allow 21116/tcp && \ 30 | ufw allow 21116/udp && \ 31 | ufw allow 21118/tcp && \ 32 | mkdir -p /opt/rustdesk && \ 33 | cat > /opt/rustdesk/docker-compose.yml < 49 | EOF 50 | docker-compose -f /opt/rustdesk/docker-compose.yml up -d 51 | " 52 | 53 | echo "RustDesk Server installation in LXC $LXC_ID completed successfully!" 54 | -------------------------------------------------------------------------------- /proxmox/lxc/debian_lxc_git.sh: -------------------------------------------------------------------------------- 1 | # !/bin/bash 2 | # Description: Proxmox LXC setup script for Debian with optional GitHub script fetching 3 | # Version: 1.1 4 | # ProjectL: Lonewolf Scripts 5 | # Created by: Clark Industries IO 6 | 7 | # Check if whiptail is installed 8 | if ! command -v whiptail &> /dev/null; then 9 | echo "Whiptail is required but not installed. Install it using: sudo apt-get install whiptail" 10 | exit 1 11 | fi 12 | 13 | # Ensure template list is updated 14 | pveam update > /dev/null 15 | 16 | # Get available Debian templates 17 | TEMPLATES=$(pveam available | awk '/debian/ {print $2}') 18 | if [[ -z "$TEMPLATES" ]]; then 19 | echo "No Debian templates found. Run 'pveam update' and ensure Debian templates are available." 20 | exit 1 21 | fi 22 | 23 | # Format the options for whiptail 24 | TEMPLATE_OPTIONS=() 25 | for template in $TEMPLATES; do 26 | TEMPLATE_OPTIONS+=("$template" "$template") 27 | done 28 | 29 | # Let the user select a Debian version 30 | SELECTED_TEMPLATE=$(whiptail --title "Select Debian Version" --menu "Choose a Debian LXC Template:" 30 140 10 "${TEMPLATE_OPTIONS[@]}" 3>&1 1>&2 2>&3) 31 | 32 | if [[ -z "$SELECTED_TEMPLATE" ]]; then 33 | whiptail --title "Error" --msgbox "No template selected. Exiting." 8 50 34 | exit 1 35 | fi 36 | 37 | # Ask the user if the LXC should be privileged or unprivileged 38 | PRIVILEGED_OPTION=$(whiptail --title "LXC Privilege Mode" --radiolist \ 39 | "Most LXC containers are unprivileged.\n\n\ 40 | ⚠️ WARNING: Privileged containers run with elevated permissions.\n\ 41 | Only use this if you fully understand the security risks!" \ 42 | 15 60 2 \ 43 | "Unprivileged" "" ON \ 44 | "Privileged" "" OFF \ 45 | 3>&1 1>&2 2>&3) 46 | 47 | # Check if user pressed "Cancel" 48 | EXIT_STATUS=$? 49 | # Exit on Cancel 50 | if [ $EXIT_STATUS -ne 0 ]; then 51 | echo "User cancelled. Exiting..." 52 | exit 1 53 | fi 54 | 55 | # Determine Privileged Flag 56 | if [[ "$PRIVILEGED_OPTION" == "Privileged" ]]; then 57 | PRIVILEGED_FLAG="1" 58 | FEATURES="nesting=1,fuse=1" # Exclude keyctl 59 | else 60 | PRIVILEGED_FLAG="0" 61 | FEATURES="nesting=1,keyctl=1,fuse=1" # Include keyctl for unprivileged containers 62 | fi 63 | 64 | # Get available storage options 65 | storage_options=$(pvesm status | awk 'NR>1 {print $1}' | xargs) 66 | default_storage=$(echo $storage_options | awk '{print $1}') 67 | 68 | # Convert storage options into a format suitable for whiptail menu 69 | STORAGE_SELECTION="" 70 | for s in $storage_options; do 71 | STORAGE_SELECTION+="$s Storage " # Correctly format without "off" 72 | done 73 | 74 | # GUI for LXC configuration 75 | 76 | # Get the next available LXC ID 77 | AUTO_CT_ID=$(pvesh get /cluster/nextid) 78 | 79 | # Prompt the user with the default auto-selected LXC ID 80 | CT_ID=$(whiptail --inputbox "Enter Container ID (default: $AUTO_CT_ID):" 8 50 "$AUTO_CT_ID" --title "LXC Configuration" 3>&1 1>&2 2>&3) 81 | # Check if user pressed "Cancel" 82 | EXIT_STATUS=$? 83 | # Exit on Cancel 84 | if [ $EXIT_STATUS -ne 0 ]; then 85 | echo "User cancelled. Exiting..." 86 | exit 1 87 | fi 88 | 89 | HOSTNAME=$(whiptail --inputbox "Enter Hostname:" 8 50 "debian-lxc" --title "LXC Configuration" 3>&1 1>&2 2>&3) 90 | # Check if user pressed "Cancel" 91 | EXIT_STATUS=$? 92 | # Exit on Cancel 93 | if [ $EXIT_STATUS -ne 0 ]; then 94 | echo "User cancelled. Exiting..." 95 | exit 1 96 | fi 97 | 98 | DISK_SIZE=$(whiptail --inputbox "Enter Disk Size (in GB):" 8 50 4 --title "LXC Configuration" 3>&1 1>&2 2>&3) 99 | # Check if user pressed "Cancel" 100 | EXIT_STATUS=$? 101 | # Exit on Cancel 102 | if [ $EXIT_STATUS -ne 0 ]; then 103 | echo "User cancelled. Exiting..." 104 | exit 1 105 | fi 106 | 107 | MEMORY=$(whiptail --inputbox "Enter Memory Size (in MB):" 8 50 512 --title "LXC Configuration" 3>&1 1>&2 2>&3) 108 | # Check if user pressed "Cancel" 109 | EXIT_STATUS=$? 110 | # Exit on Cancel 111 | if [ $EXIT_STATUS -ne 0 ]; then 112 | echo "User cancelled. Exiting..." 113 | exit 1 114 | fi 115 | 116 | # GUI for selecting storage 117 | STORAGE=$(whiptail --title "Select Storage" --menu \ 118 | "Choose where to store the LXC container:" 20 60 10 \ 119 | $STORAGE_SELECTION 3>&1 1>&2 2>&3) 120 | 121 | # Check if user pressed "Cancel" 122 | EXIT_STATUS=$? 123 | # Exit on Cancel 124 | if [ $EXIT_STATUS -ne 0 ]; then 125 | echo "User cancelled. Exiting..." 126 | exit 1 127 | fi 128 | 129 | # Password input with confirmation 130 | while true; do 131 | PASSWORD=$(whiptail --passwordbox "Enter Root Password:" 8 50 --title "LXC Configuration" 3>&1 1>&2 2>&3) 132 | CONFIRM_PASSWORD=$(whiptail --passwordbox "Confirm Root Password:" 8 50 --title "LXC Configuration" 3>&1 1>&2 2>&3) 133 | 134 | if [ "$PASSWORD" == "$CONFIRM_PASSWORD" ]; then 135 | break 136 | else 137 | whiptail --title "Error" --msgbox "Passwords do not match. Please try again." 8 50 138 | fi 139 | done 140 | 141 | # Network Configuration 142 | NET_TYPE=$(whiptail --title "Network Configuration" --menu "Choose Network Type:" 15 50 2 \ 143 | "dhcp" "Use DHCP (Automatic IP)" \ 144 | "static" "Set Static IP Address" 3>&1 1>&2 2>&3) 145 | 146 | if [[ "$NET_TYPE" == "static" ]]; then 147 | IP_ADDR=$(whiptail --inputbox "Enter Static IP Address (e.g., 192.168.1.100/24):" 10 60 "192.168.1.100/24" --title "Static IP Configuration" 3>&1 1>&2 2>&3) 148 | 149 | GATEWAY=$(whiptail --inputbox "Enter Gateway (default: 192.168.1.1):" 10 60 "192.168.1.1" --title "Gateway Configuration" 3>&1 1>&2 2>&3) 150 | 151 | DNS_OPTION=$(whiptail --title "DNS Configuration" --menu "Choose DNS Configuration:" 15 50 2 \ 152 | "auto" "Use Default DNS (Proxmox Resolver)" \ 153 | "manual" "Enter Custom DNS" 3>&1 1>&2 2>&3) 154 | 155 | if [[ "$DNS_OPTION" == "manual" ]]; then 156 | DNS_SERVERS=$(whiptail --inputbox "Enter DNS Servers (e.g., 8.8.8.8 1.1.1.1):" 10 60 "8.8.8.8 1.1.1.1" --title "DNS Configuration" 3>&1 1>&2 2>&3) 157 | else 158 | DNS_SERVERS="" 159 | fi 160 | else 161 | IP_ADDR="dhcp" 162 | GATEWAY="" 163 | DNS_SERVERS="" 164 | fi 165 | 166 | # Confirm settings 167 | whiptail --title "Confirm Settings" --yesno "Container ID: $CT_ID\nHostname: $HOSTNAME\nDebian Version: $SELECTED_TEMPLATE\nDisk Size: ${DISK_SIZE}G\nMemory: ${MEMORY}MB\nStorage: $STORAGE\nNetwork: $NET_TYPE\nStatic IP: $IP_ADDR\nGateway: $GATEWAY\nDNS: ${DNS_SERVERS:-Auto}\n\nProceed?" 20 60 168 | if [ $? -ne 0 ]; then 169 | echo "Aborted." 170 | exit 1 171 | fi 172 | 173 | # Check if template exists locally, download if missing 174 | if ! pveam list local | grep -q "$SELECTED_TEMPLATE"; then 175 | echo "Template $SELECTED_TEMPLATE not found locally. Downloading..." 176 | pveam download local $SELECTED_TEMPLATE 177 | if [[ $? -ne 0 ]]; then 178 | echo "Failed to download $SELECTED_TEMPLATE. Exiting." 179 | exit 1 180 | fi 181 | fi 182 | 183 | # Create LXC container 184 | echo "Creating LXC container..." 185 | pct create $CT_ID local:vztmpl/$SELECTED_TEMPLATE \ 186 | -hostname $HOSTNAME \ 187 | -storage $STORAGE \ 188 | -rootfs ${STORAGE}:${DISK_SIZE} \ 189 | -memory $MEMORY \ 190 | -password $PASSWORD \ 191 | -net0 "name=eth0,bridge=vmbr0,ip=$IP_ADDR$( [[ -n "$GATEWAY" ]] && echo ",gw=$GATEWAY")" 192 | -features $FEATURES \ 193 | -unprivileged $PRIVILEGED_FLAG 194 | 195 | # Apply DNS settings if set 196 | if [[ -n "$DNS_SERVERS" ]]; then 197 | echo "Setting custom DNS servers..." 198 | echo "nameserver $DNS_SERVERS" > /etc/pve/lxc/${CT_ID}.conf 199 | fi 200 | 201 | echo "Starting LXC container..." 202 | pct start $CT_ID 203 | 204 | # Ask whether to fetch scripts from GitHub 205 | USE_GITHUB=$(whiptail --title "External Scripts" --yesno "Do you want to fetch installation scripts from GitHub?" 8 50 3>&1 1>&2 2>&3) 206 | if [[ $? -eq 0 ]]; then 207 | # Ask for GitHub script URLs 208 | GITHUB_URLS=$(whiptail --inputbox "Enter GitHub script URLs (space-separated):" 10 60 --title "GitHub Script Fetch" 3>&1 1>&2 2>&3) 209 | EXTERNAL_SCRIPTS_DIR="/root/lxc-scripts" 210 | 211 | # Create the directory if it doesn't exist 212 | mkdir -p "$EXTERNAL_SCRIPTS_DIR" 213 | 214 | # Download scripts from GitHub 215 | for url in $GITHUB_URLS; do 216 | script_name=$(basename "$url") 217 | script_path="$EXTERNAL_SCRIPTS_DIR/$script_name" 218 | 219 | # Download and make the script executable 220 | wget -q "$url" -O "$script_path" 221 | chmod +x "$script_path" 222 | done 223 | fi 224 | 225 | # Run scripts on Proxmox (not inside LXC) 226 | if [ -d "$EXTERNAL_SCRIPTS_DIR" ] && [ "$(ls -A "$EXTERNAL_SCRIPTS_DIR"/*.sh 2>/dev/null)" ]; then 227 | for script in "$EXTERNAL_SCRIPTS_DIR"/*.sh; do 228 | echo "Running $(basename "$script") on Proxmox..." 229 | bash "$script" "$CT_ID" 230 | done 231 | 232 | # Optional: Clean up scripts after execution 233 | rm -rf "$EXTERNAL_SCRIPTS_DIR" 234 | echo "Removed downloaded scripts." 235 | else 236 | echo "No scripts found in $EXTERNAL_SCRIPTS_DIR. Skipping execution." 237 | fi 238 | 239 | # Remove the installer script itself 240 | rm -- "$0" 241 | 242 | echo "LXC Container $CT_ID setup complete!" 243 | whiptail --title "Setup Complete" --msgbox "LXC Container $CT_ID setup is complete!" 8 50 244 | -------------------------------------------------------------------------------- /proxmox/lxc/lxc_update_selectable.sh: -------------------------------------------------------------------------------- 1 | # !/bin/bash 2 | # Description: Update selected LXC containers on Proxmox VE 3 | # Tested: Proxmox VE 8.0+ (Bookworm) 4 | # Version: 1.0 5 | # Created by: Clark Industries IO 6 | 7 | # Check if whiptail is installed 8 | if ! command -v whiptail &> /dev/null; then 9 | echo "Whiptail is required but not installed. Install it using: apt-get install whiptail" 10 | exit 1 11 | fi 12 | 13 | # Get a list of existing LXC containers 14 | EXISTING_CONTAINERS=$(pct list | awk 'NR>1 {print $1, $3}' | xargs -n2) 15 | 16 | # If no containers exist, exit 17 | if [[ -z "$EXISTING_CONTAINERS" ]]; then 18 | whiptail --title "No Containers Found" --msgbox "There are no existing LXC containers to update." 8 50 19 | exit 1 20 | fi 21 | 22 | # Format for whiptail checklist (Container ID + Name) 23 | CONTAINER_SELECTION="" 24 | while read -r ID NAME; do 25 | CONTAINER_SELECTION+="$ID $NAME OFF " 26 | done <<< "$EXISTING_CONTAINERS" 27 | 28 | # Show whiptail checklist 29 | SELECTED_CONTAINERS=$(whiptail --title "Select Containers to Update" --checklist \ 30 | "Select the containers you want to update:" 20 60 10 $CONTAINER_SELECTION 3>&1 1>&2 2>&3) 31 | 32 | # If the user cancels, exit 33 | if [[ $? -ne 0 ]]; then 34 | whiptail --title "Operation Cancelled" --msgbox "Update cancelled. Exiting." 8 50 35 | exit 1 36 | fi 37 | 38 | # Convert selection to a list 39 | if [[ -n "$SELECTED_CONTAINERS" ]]; then 40 | for CT_ID in $SELECTED_CONTAINERS; do 41 | CT_ID=$(echo "$CT_ID" | tr -d '"') # Remove quotes from whiptail output 42 | echo "Updating LXC container $CT_ID..." 43 | pct exec "$CT_ID" -- apt update && apt upgrade -y 44 | whiptail --title "Update Complete" --msgbox "LXC $CT_ID has been updated successfully!" 8 50 45 | done 46 | else 47 | whiptail --title "No Containers Selected" --msgbox "No containers were selected for updating." 8 50 48 | exit 1 49 | fi 50 | -------------------------------------------------------------------------------- /proxmox/lxc/ubuntu_lxc_git.sh: -------------------------------------------------------------------------------- 1 | # !/bin/bash 2 | # Description: Proxmox LXC setup script for Ubuntu with optional GitHub script fetching 3 | # Tested: Proxmox VE 8.0+ (Bookworm) 4 | # Version: 1.0 5 | # Created by: Clark Industries IO 6 | 7 | # Check if whiptail is installed 8 | if ! command -v whiptail &> /dev/null; then 9 | echo "Whiptail is required but not installed. Install it using: apt-get install whiptail" 10 | exit 1 11 | fi 12 | 13 | # Ensure template list is updated 14 | pveam update > /dev/null 15 | 16 | # Get available Ubuntu templates 17 | TEMPLATES=$(pveam available | awk '/ubuntu/ {print $2}') 18 | if [[ -z "$TEMPLATES" ]]; then 19 | echo "No Ubuntu templates found. Run 'pveam update' and ensure Ubuntu templates are available." 20 | exit 1 21 | fi 22 | 23 | # Format the options for whiptail 24 | TEMPLATE_OPTIONS=() 25 | for template in $TEMPLATES; do 26 | TEMPLATE_OPTIONS+=("$template" "$template") 27 | done 28 | 29 | # Let the user select a Ubuntu version 30 | SELECTED_TEMPLATE=$(whiptail --title "Select Ubuntu Version" --menu "Choose a Ubuntu LXC Template:" 30 140 10 "${TEMPLATE_OPTIONS[@]}" 3>&1 1>&2 2>&3) 31 | 32 | if [[ -z "$SELECTED_TEMPLATE" ]]; then 33 | whiptail --title "Error" --msgbox "No template selected. Exiting." 8 50 34 | exit 1 35 | fi 36 | 37 | # Ask the user if the LXC should be privileged or unprivileged 38 | PRIVILEGED_OPTION=$(whiptail --title "LXC Privilege Mode" --radiolist \ 39 | "Most LXC containers are unprivileged.\n\n\ 40 | ⚠️ WARNING: Privileged containers run with elevated permissions.\n\ 41 | Only use this if you fully understand the security risks!" \ 42 | 15 60 2 \ 43 | "Unprivileged" "" ON \ 44 | "Privileged" "" OFF \ 45 | 3>&1 1>&2 2>&3) 46 | 47 | # Check if user pressed "Cancel" 48 | EXIT_STATUS=$? 49 | # Exit on Cancel 50 | if [ $EXIT_STATUS -ne 0 ]; then 51 | echo "User cancelled. Exiting..." 52 | exit 1 53 | fi 54 | 55 | # Determine Privileged Flag 56 | if [[ "$PRIVILEGED_OPTION" == "Privileged" ]]; then 57 | PRIVILEGED_FLAG="1" 58 | FEATURES="nesting=1,fuse=1" # Exclude keyctl 59 | else 60 | PRIVILEGED_FLAG="0" 61 | FEATURES="nesting=1,keyctl=1,fuse=1" # Include keyctl for unprivileged containers 62 | fi 63 | 64 | # Get available storage options 65 | storage_options=$(pvesm status | awk 'NR>1 {print $1}' | xargs) 66 | default_storage=$(echo $storage_options | awk '{print $1}') 67 | 68 | # Convert storage options into a format suitable for whiptail menu 69 | STORAGE_SELECTION="" 70 | for s in $storage_options; do 71 | STORAGE_SELECTION+="$s Storage " # Correctly format without "off" 72 | done 73 | 74 | # GUI for LXC configuration 75 | 76 | # Function to find the next available LXC ID (starting from 101) 77 | get_next_lxc_id() { 78 | local START_ID=101 79 | local NEXT_ID=$START_ID 80 | 81 | while pct list | awk 'NR>1 {print $1}' | grep -q "^$NEXT_ID$"; do 82 | ((NEXT_ID++)) 83 | done 84 | 85 | echo "$NEXT_ID" 86 | } 87 | 88 | # Get the next available LXC ID 89 | AUTO_CT_ID=$(get_next_lxc_id) 90 | 91 | # Prompt the user with the default auto-selected LXC ID 92 | CT_ID=$(whiptail --inputbox "Enter Container ID (default: $AUTO_CT_ID):" 8 50 "$AUTO_CT_ID" --title "LXC Configuration" 3>&1 1>&2 2>&3) 93 | # Check if user pressed "Cancel" 94 | EXIT_STATUS=$? 95 | # Exit on Cancel 96 | if [ $EXIT_STATUS -ne 0 ]; then 97 | echo "User cancelled. Exiting..." 98 | exit 1 99 | fi 100 | 101 | HOSTNAME=$(whiptail --inputbox "Enter Hostname:" 8 50 "ubuntu-lxc" --title "LXC Configuration" 3>&1 1>&2 2>&3) 102 | # Check if user pressed "Cancel" 103 | EXIT_STATUS=$? 104 | # Exit on Cancel 105 | if [ $EXIT_STATUS -ne 0 ]; then 106 | echo "User cancelled. Exiting..." 107 | exit 1 108 | fi 109 | 110 | DISK_SIZE=$(whiptail --inputbox "Enter Disk Size (in GB):" 8 50 4 --title "LXC Configuration" 3>&1 1>&2 2>&3) 111 | # Check if user pressed "Cancel" 112 | EXIT_STATUS=$? 113 | # Exit on Cancel 114 | if [ $EXIT_STATUS -ne 0 ]; then 115 | echo "User cancelled. Exiting..." 116 | exit 1 117 | fi 118 | 119 | MEMORY=$(whiptail --inputbox "Enter Memory Size (in MB):" 8 50 512 --title "LXC Configuration" 3>&1 1>&2 2>&3) 120 | # Check if user pressed "Cancel" 121 | EXIT_STATUS=$? 122 | # Exit on Cancel 123 | if [ $EXIT_STATUS -ne 0 ]; then 124 | echo "User cancelled. Exiting..." 125 | exit 1 126 | fi 127 | 128 | # GUI for selecting storage 129 | STORAGE=$(whiptail --title "Select Storage" --menu \ 130 | "Choose where to store the LXC container:" 20 60 10 \ 131 | $STORAGE_SELECTION 3>&1 1>&2 2>&3) 132 | 133 | # Check if user pressed "Cancel" 134 | # Check if user pressed "Cancel" 135 | EXIT_STATUS=$? 136 | # Exit on Cancel 137 | if [ $EXIT_STATUS -ne 0 ]; then 138 | echo "User cancelled. Exiting..." 139 | exit 1 140 | fi 141 | 142 | # Password input with confirmation 143 | while true; do 144 | PASSWORD=$(whiptail --passwordbox "Enter Root Password:" 8 50 --title "LXC Configuration" 3>&1 1>&2 2>&3) 145 | CONFIRM_PASSWORD=$(whiptail --passwordbox "Confirm Root Password:" 8 50 --title "LXC Configuration" 3>&1 1>&2 2>&3) 146 | 147 | if [ "$PASSWORD" == "$CONFIRM_PASSWORD" ]; then 148 | break 149 | else 150 | whiptail --title "Error" --msgbox "Passwords do not match. Please try again." 8 50 151 | fi 152 | done 153 | 154 | # Network Configuration 155 | NET_TYPE=$(whiptail --title "Network Configuration" --menu "Choose Network Type:" 15 50 2 \ 156 | "dhcp" "Use DHCP (Automatic IP)" \ 157 | "static" "Set Static IP Address" 3>&1 1>&2 2>&3) 158 | 159 | if [[ "$NET_TYPE" == "static" ]]; then 160 | IP_ADDR=$(whiptail --inputbox "Enter Static IP Address (e.g., 192.168.1.100/24):" 10 60 "192.168.1.100/24" --title "Static IP Configuration" 3>&1 1>&2 2>&3) 161 | 162 | GATEWAY=$(whiptail --inputbox "Enter Gateway (default: 192.168.1.1):" 10 60 "192.168.1.1" --title "Gateway Configuration" 3>&1 1>&2 2>&3) 163 | 164 | DNS_OPTION=$(whiptail --title "DNS Configuration" --menu "Choose DNS Configuration:" 15 50 2 \ 165 | "auto" "Use Default DNS (Proxmox Resolver)" \ 166 | "manual" "Enter Custom DNS" 3>&1 1>&2 2>&3) 167 | 168 | if [[ "$DNS_OPTION" == "manual" ]]; then 169 | DNS_SERVERS=$(whiptail --inputbox "Enter DNS Servers (e.g., 8.8.8.8 1.1.1.1):" 10 60 "8.8.8.8 1.1.1.1" --title "DNS Configuration" 3>&1 1>&2 2>&3) 170 | else 171 | DNS_SERVERS="" 172 | fi 173 | else 174 | IP_ADDR="dhcp" 175 | GATEWAY="" 176 | DNS_SERVERS="" 177 | fi 178 | 179 | # Confirm settings 180 | whiptail --title "Confirm Settings" --yesno "Container ID: $CT_ID\nHostname: $HOSTNAME\nUbuntu Version: $SELECTED_TEMPLATE\nDisk Size: ${DISK_SIZE}G\nMemory: ${MEMORY}MB\nStorage: $STORAGE\nNetwork: $NET_TYPE\nStatic IP: $IP_ADDR\nGateway: $GATEWAY\nDNS: ${DNS_SERVERS:-Auto}\n\nProceed?" 20 60 181 | if [ $? -ne 0 ]; then 182 | echo "Aborted." 183 | exit 1 184 | fi 185 | 186 | # Check if template exists locally, download if missing 187 | if ! pveam list local | grep -q "$SELECTED_TEMPLATE"; then 188 | echo "Template $SELECTED_TEMPLATE not found locally. Downloading..." 189 | pveam download local $SELECTED_TEMPLATE 190 | if [[ $? -ne 0 ]]; then 191 | echo "Failed to download $SELECTED_TEMPLATE. Exiting." 192 | exit 1 193 | fi 194 | fi 195 | 196 | # Create LXC container 197 | echo "Creating LXC container..." 198 | pct create $CT_ID local:vztmpl/$SELECTED_TEMPLATE \ 199 | -hostname $HOSTNAME \ 200 | -storage $STORAGE \ 201 | -rootfs ${STORAGE}:${DISK_SIZE} \ 202 | -memory $MEMORY \ 203 | -password $PASSWORD \ 204 | -net0 "name=eth0,bridge=vmbr0,ip=$IP_ADDR$( [[ -n "$GATEWAY" ]] && echo ",gw=$GATEWAY")" 205 | -features $FEATURES \ 206 | -unprivileged $PRIVILEGED_FLAG 207 | 208 | # Apply DNS settings if set 209 | if [[ -n "$DNS_SERVERS" ]]; then 210 | echo "Setting custom DNS servers..." 211 | echo "nameserver $DNS_SERVERS" > /etc/pve/lxc/${CT_ID}.conf 212 | fi 213 | 214 | echo "Starting LXC container..." 215 | pct start $CT_ID 216 | 217 | # Ask whether to fetch scripts from GitHub 218 | USE_GITHUB=$(whiptail --title "External Scripts" --yesno "Do you want to fetch installation scripts from GitHub?" 8 50 3>&1 1>&2 2>&3) 219 | if [[ $? -eq 0 ]]; then 220 | # Ask for GitHub script URLs 221 | GITHUB_URLS=$(whiptail --inputbox "Enter GitHub script URLs (space-separated):" 10 60 --title "GitHub Script Fetch" 3>&1 1>&2 2>&3) 222 | EXTERNAL_SCRIPTS_DIR="/root/lxc-scripts" 223 | 224 | # Create the directory if it doesn't exist 225 | mkdir -p "$EXTERNAL_SCRIPTS_DIR" 226 | 227 | # Download scripts from GitHub 228 | for url in $GITHUB_URLS; do 229 | script_name=$(basename "$url") 230 | script_path="$EXTERNAL_SCRIPTS_DIR/$script_name" 231 | 232 | # Download and make the script executable 233 | wget -q "$url" -O "$script_path" 234 | chmod +x "$script_path" 235 | done 236 | fi 237 | 238 | # Run scripts on Proxmox (not inside LXC) 239 | if [ -d "$EXTERNAL_SCRIPTS_DIR" ] && [ "$(ls -A "$EXTERNAL_SCRIPTS_DIR"/*.sh 2>/dev/null)" ]; then 240 | for script in "$EXTERNAL_SCRIPTS_DIR"/*.sh; do 241 | echo "Running $(basename "$script") on Proxmox..." 242 | bash "$script" "$CT_ID" 243 | done 244 | 245 | # Optional: Clean up scripts after execution 246 | rm -rf "$EXTERNAL_SCRIPTS_DIR" 247 | echo "Removed downloaded scripts." 248 | else 249 | echo "No scripts found in $EXTERNAL_SCRIPTS_DIR. Skipping execution." 250 | fi 251 | 252 | # Remove the installer script itself 253 | rm -- "$0" 254 | 255 | echo "LXC Container $CT_ID setup complete!" 256 | whiptail --title "Setup Complete" --msgbox "LXC Container $CT_ID setup is complete!" 8 50 257 | -------------------------------------------------------------------------------- /proxmox/pve_update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Proxmox VE Update Script 3 | # This script will update Proxmox VE to the latest version. 4 | # It will also allow you to select the Proxmox repository to use. 5 | # This script is intended for use on Proxmox VE installations. 6 | # Tested on Proxmox VE 8.0+ (Bookworm) 7 | # Version: 1.1 8 | # Created By: Clark Industries IO 9 | 10 | # Ensure the script is run as root 11 | if [ "$EUID" -ne 0 ]; then 12 | echo "Please run as root" 13 | exit 14 | fi 15 | 16 | # Function to configure Proxmox repository 17 | configure_repository() { 18 | REPO_CHOICE=$(whiptail --title "Proxmox Repository Selection" --menu \ 19 | "Choose which Proxmox repository to use:\n(Only one will be active)" 15 80 3 \ 20 | "no-subscription" "Default: No-Subscription Repository (Recommended)" \ 21 | "enterprise" "Enterprise Repository (Requires a valid subscription)" \ 22 | "test" "Test Repository (Use with caution!)" 3>&1 1>&2 2>&3) 23 | 24 | # If the user cancels, exit 25 | if [[ $? -ne 0 ]]; then 26 | whiptail --title "Operation Cancelled" --msgbox "Repository selection cancelled. Exiting." 8 50 27 | exit 1 28 | fi 29 | 30 | # Define repo paths 31 | NO_SUBSCRIPTION_REPO="/etc/apt/sources.list.d/pve-no-subscription.list" 32 | ENTERPRISE_REPO="/etc/apt/sources.list.d/pve-enterprise.list" 33 | TEST_REPO="/etc/apt/sources.list.d/pve-test.list" 34 | 35 | # Define repository entries 36 | NO_SUBSCRIPTION_ENTRY="deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription" 37 | ENTERPRISE_ENTRY="deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise" 38 | TEST_ENTRY="deb http://download.proxmox.com/debian/pve bookworm pvetest" 39 | 40 | # Function to enable selected repo and disable others 41 | set_active_repo() { 42 | local active_file="$1" 43 | local active_entry="$2" 44 | 45 | # Disable other repos 46 | for repo in "$NO_SUBSCRIPTION_REPO" "$ENTERPRISE_REPO" "$TEST_REPO"; do 47 | if [[ -f "$repo" && "$repo" != "$active_file" ]]; then 48 | echo "[INFO] Disabling repository: $repo" 49 | mv "$repo" "$repo.disabled" 50 | fi 51 | done 52 | 53 | # Enable selected repo 54 | if [[ -f "$active_file.disabled" ]]; then 55 | echo "[INFO] Re-enabling repository: $active_file" 56 | mv "$active_file.disabled" "$active_file" 57 | fi 58 | 59 | # Add repo if missing 60 | if ! grep -qxF "$active_entry" "$active_file" 2>/dev/null; then 61 | echo "[INFO] Adding repository: $active_entry" 62 | echo "$active_entry" | tee "$active_file" > /dev/null 63 | else 64 | echo "[INFO] Repository already active: $active_file" 65 | fi 66 | } 67 | 68 | # Apply the selected repository 69 | case "$REPO_CHOICE" in 70 | "no-subscription") set_active_repo "$NO_SUBSCRIPTION_REPO" "$NO_SUBSCRIPTION_ENTRY" ;; 71 | "enterprise") set_active_repo "$ENTERPRISE_REPO" "$ENTERPRISE_ENTRY" ;; 72 | "test") set_active_repo "$TEST_REPO" "$TEST_ENTRY" ;; 73 | esac 74 | 75 | # Update package list 76 | echo "Updating package lists..." 77 | apt update 78 | 79 | whiptail --title "Repository Configured" --msgbox "The Proxmox repository has been set to '$REPO_CHOICE'.\nUnused repositories have been disabled.\nPackages updated successfully!" 10 60 80 | } 81 | 82 | # Run the function 83 | configure_repository 84 | 85 | # Confirm settings 86 | whiptail --title "Confirm Settings" --yesno "Are you sure you want to update ProxmoxVE?" 20 60 87 | 88 | # Check if user pressed "no" 89 | if [[ $? -ne 0 ]]; then 90 | whiptail --title "Operation Cancelled" --msgbox "Exited Update." 8 50 91 | exit 1 92 | fi 93 | 94 | whiptail --title "Updating" --infobox "Updating ProxmoxVE...please wait..." 8 40 95 | 96 | # updating to latest version 97 | echo "Upgrading installed packages..." 98 | apt-get upgrade -y 99 | 100 | # updating to latest version 101 | echo "Performing dist-upgrade..." 102 | apt-get dist-upgrade -y 103 | 104 | # removes old files 105 | echo "Removing unused packages..." 106 | apt-get autoremove -y 107 | 108 | # Clean up update files 109 | echo "Cleaning up package cache..." 110 | apt-get clean 111 | 112 | # completed update confirmation 113 | whiptail --title "Update Complete" --msgbox "Proxmox has been from '$REPO_CHOICE'.\nPackages updated successfully!" 10 60 114 | 115 | # Check if a reboot is required 116 | if [ -f /var/run/reboot-required ]; then 117 | whiptail --title "Reboot Required" --yesno "A system reboot is required to complete the updates. Do you want to reboot now?" 10 60 118 | 119 | # Check if the user selected "Yes" 120 | if [[ $? -eq 0 ]]; then 121 | echo "Rebooting in 10 seconds..." 122 | sleep 10 123 | reboot 124 | else 125 | echo "Reboot canceled by user. Update completed without reboot." 126 | fi -------------------------------------------------------------------------------- /proxmox/ultra_scripts/enhanced_vm_lxc_install.sh: -------------------------------------------------------------------------------- 1 | # !/bin/bash 2 | # Description: Proxmox LXC or VM Creation Script 3 | # Version: 1.1 4 | # ProjectL: Lonewolf Scripts 5 | # Created by: Clark Industries IO 6 | 7 | # Ensure whiptail is installed 8 | if ! command -v whiptail &> /dev/null; then 9 | echo "Whiptail is required but not installed. Install it using: apt-get install whiptail" 10 | exit 1 11 | fi 12 | 13 | # Choose instance type 14 | CHOSEN_TYPE=$(whiptail --title "Choose VM or LXC" --menu "Select the type of instance to create:" 15 50 2 \ 15 | "VM" "Create a Virtual Machine" \ 16 | "LXC" "Create a Linux Container" 3>&1 1>&2 2>&3) 17 | 18 | if [[ $? -ne 0 ]]; then 19 | whiptail --title "Operation Cancelled" --msgbox "Instance creation cancelled." 8 50 20 | exit 1 21 | fi 22 | 23 | # Get the next available ID 24 | AUTO_ID=$(pvesh get /cluster/nextid) 25 | if [[ $? -ne 0 ]]; then 26 | whiptail --title "Error" --msgbox "Failed to get next available ID." 8 50 27 | exit 1 28 | fi 29 | # Part 1: Common Configuration 30 | whiptail --title "Custom Configuration: Part 1" --msgbox "Enter common configuration for $CHOSEN_TYPE" 8 50 31 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 32 | 33 | # Select Instance ID 34 | INSTANCE_ID=$(whiptail --inputbox "Enter Instance ID (default: $AUTO_ID):" 8 50 "$AUTO_ID" --title "$CHOSEN_TYPE Configuration" 3>&1 1>&2 2>&3) 35 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 36 | # Select Hostname 37 | INSTANCE_NAME=$(whiptail --inputbox "Enter Hostname:" 8 50 "${CHOSEN_TYPE,,}-$INSTANCE_ID" --title "$CHOSEN_TYPE Configuration" 3>&1 1>&2 2>&3) 38 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 39 | # Select Disk Size 40 | DISK_SIZE=$(whiptail --inputbox "Enter Disk Size (GB):" 8 50 10 --title "$CHOSEN_TYPE Configuration" 3>&1 1>&2 2>&3) 41 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 42 | # Select CPU Cores 43 | CPU_CORES=$(whiptail --inputbox "Enter Number of CPU Cores:" 8 50 2 --title "$CHOSEN_TYPE Configuration" 3>&1 1>&2 2>&3) 44 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 45 | # Select Memory Size 46 | MEMORY=$(whiptail --inputbox "Enter Memory Size (MB):" 8 50 2048 --title "$CHOSEN_TYPE Configuration" 3>&1 1>&2 2>&3) 47 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 48 | 49 | # Get available storage from Proxmox 50 | STORAGE_OPTIONS=$(pvesm status | awk 'NR>1 {print $1}') 51 | DEFAULT_STORAGE=$(echo "$STORAGE_OPTIONS" | awk '{print $1}') 52 | 53 | STORAGE=$(whiptail --menu "Select Storage:" 15 50 5 $(for s in $STORAGE_OPTIONS; do echo "$s _"; done) --default-item "$DEFAULT_STORAGE" 3>&1 1>&2 2>&3) 54 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 55 | 56 | # Handle VM Creation 57 | if [[ "$CHOSEN_TYPE" == "VM" ]]; then 58 | whiptail --title "Custom Configuration: Part 2" --msgbox "$CHOSEN_TYPE Specifc Configuration Settings, Please Contiune." 8 50 59 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 60 | # Get ISO Images 61 | ISO_STORAGE_PATH="/var/lib/vz/template/iso" 62 | mkdir -p "$ISO_STORAGE_PATH" 63 | 64 | ISO_OPTIONS=() 65 | EXISTING_ISOS=$(ls "$ISO_STORAGE_PATH" 2>/dev/null | grep -E "\.iso$") 66 | 67 | # Add existing ISOs to selection menu 68 | if [[ -z "$EXISTING_ISOS" ]]; then 69 | ISO_OPTIONS+=("No existing ISOs found" "") 70 | else 71 | for iso in $EXISTING_ISOS; do 72 | ISO_OPTIONS+=("$iso" "Use existing ISO: $iso") 73 | done 74 | fi 75 | 76 | # Option to download a new ISO 77 | ISO_OPTIONS+=("Download New ISO" "Enter URL to download a new ISO") 78 | 79 | SELECTED_ISO=$(whiptail --title "Select ISO" --menu "Choose an ISO for your VM or download a new one:" 20 60 10 "${ISO_OPTIONS[@]}" 3>&1 1>&2 2>&3) 80 | 81 | if [[ $? -ne 0 ]]; then exit 1; fi 82 | 83 | # Handle ISO selection 84 | if [[ "$SELECTED_ISO" == "Download New ISO" ]]; then 85 | ISO_URL=$(whiptail --inputbox "Enter the direct URL to the ISO file:" 10 60 --title "Download ISO" 3>&1 1>&2 2>&3) 86 | 87 | if [[ $? -ne 0 || -z "$ISO_URL" ]]; then exit 1; fi 88 | 89 | ISO_FILENAME="${ISO_URL##*/}" 90 | ISO_PATH="$ISO_STORAGE_PATH/$ISO_FILENAME" 91 | 92 | echo "Downloading ISO: $ISO_FILENAME" 93 | 94 | # Download with progress display 95 | wget --progress=bar:force -O "$ISO_PATH" "$ISO_URL" 2>&1 | tail -f -n +6 96 | 97 | if [[ $? -ne 0 ]]; then 98 | whiptail --title "Download Failed" --msgbox "Failed to download ISO. Please check the URL and try again." 8 60 99 | exit 1 100 | fi 101 | 102 | echo "Download completed: $ISO_FILENAME" 103 | SELECTED_ISO="$ISO_FILENAME" 104 | fi 105 | 106 | # Ensure Proxmox recognizes the ISO 107 | pvesm set local --content iso 108 | echo "ISO Ready: $SELECTED_ISO" 109 | 110 | # Create VM using qm command 111 | qm create $INSTANCE_ID --name $INSTANCE_NAME --memory $MEMORY \ 112 | --net0 "virtio,bridge=vmbr0" \ 113 | --cdrom local:iso/$SELECTED_ISO --scsihw virtio-scsi-pci \ 114 | --boot c --agent 1 --sockets 1 --cores $CPU_CORES --cpu host \ 115 | --scsi0 $STORAGE:$DISK_SIZE --ide2 $STORAGE:cloudinit 116 | # Ask if user wants to start the VM 117 | if whiptail --yesno "Do you want to start the VM now?" 8 50 --title "Start VM"; then 118 | qm start $INSTANCE_ID 119 | whiptail --title "VM Started" --msgbox "VM ID $INSTANCE_ID has been started!" 8 50 120 | fi 121 | fi 122 | 123 | # Handle LXC Creation 124 | if [[ "$CHOSEN_TYPE" == "LXC" ]]; then 125 | whiptail --title "Custom Configuration: Part 2" --msgbox "$CHOSEN_TYPE Specifc Configuration Settings, Please Contiune." 8 50 126 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 127 | # Get LXC templates 128 | pveam update > /dev/null 129 | DISTRO=$(whiptail --menu "Choose LXC Base OS:" 15 50 2 "Debian" "Use a Debian template" "Ubuntu" "Use an Ubuntu template" 3>&1 1>&2 2>&3) 130 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 131 | TEMPLATE_LIST=$(pveam available | grep -i "$DISTRO" | awk '{print $2}') 132 | TEMPLATE=$(whiptail --menu "Select a $DISTRO template:" 30 110 6 $(for t in $TEMPLATE_LIST; do echo "$t _"; done) 3>&1 1>&2 2>&3) 133 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 134 | 135 | PRIVILEGED=$(whiptail --yesno "Enable Privileged Mode? Most LXCs are unprivileged." 12 50 --title "LXC Privileged Mode" 3>&1 1>&2 2>&3) 136 | [[ $? -eq 0 ]] && LXC_PRIV="1" || LXC_PRIV="0" 137 | [[ "$LXC_PRIV" == "0" ]] && LXC_KEYCTL="on" || LXC_KEYCTL="off" 138 | # Password Configuration 139 | while true; do 140 | PASSWORD=$(whiptail --passwordbox "Enter Root Password:" 8 50 --title "LXC Configuration" 3>&1 1>&2 2>&3) 141 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 142 | CONFIRM_PASSWORD=$(whiptail --passwordbox "Confirm Root Password:" 8 50 --title "LXC Configuration" 3>&1 1>&2 2>&3) 143 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 144 | if [[ "$PASSWORD" == "$CONFIRM_PASSWORD" ]]; then 145 | break 146 | else 147 | whiptail --title "Error" --msgbox "Passwords do not match. Please try again." 8 50 148 | fi 149 | done 150 | 151 | # Network Configuration for LXC only 152 | NET_TYPE=$(whiptail --title "Network Configuration" --menu "Choose Network Type:" 15 50 2 \ 153 | "dhcp" "Use DHCP (Automatic IP)" \ 154 | "static" "Set Static IP Address" 3>&1 1>&2 2>&3) 155 | 156 | if [[ "$NET_TYPE" == "static" ]]; then 157 | IP_ADDR=$(whiptail --inputbox "Enter Static IP Address (e.g., 192.168.1.100/24):" 10 60 "192.168.1.100/24" --title "Static IP Configuration" 3>&1 1>&2 2>&3) 158 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 159 | GATEWAY=$(whiptail --inputbox "Enter Gateway (default: 192.168.1.1):" 10 60 "192.168.1.1" --title "Gateway Configuration" 3>&1 1>&2 2>&3) 160 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 161 | DNS_OPTION=$(whiptail --title "DNS Configuration" --menu "Choose DNS Configuration:" 15 50 2 \ 162 | "auto" "Use Default DNS (Proxmox Resolver)" \ 163 | "manual" "Enter Custom DNS" 3>&1 1>&2 2>&3) 164 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 165 | if [[ "$DNS_OPTION" == "manual" ]]; then 166 | DNS_SERVERS=$(whiptail --inputbox "Enter DNS Servers (e.g., 8.8.8.8 1.1.1.1):" 10 60 "8.8.8.8 1.1.1.1" --title "DNS Configuration" 3>&1 1>&2 2>&3) 167 | if [[ $? -ne 0 ]]; then { echo "User cancelled. Exiting..."; exit 1; } fi 168 | else 169 | DNS_SERVERS="" 170 | fi 171 | else 172 | IP_ADDR="dhcp" 173 | GATEWAY="" 174 | DNS_SERVERS="" 175 | fi 176 | # Confirm LXC settings 177 | whiptail --title "Confirm Settings" --yesno "Container ID: $INSTANCE_ID\nHostname: $INSTANCE_NAME\n$DISTRO Version: $TEMPLATE\nDisk Size: ${DISK_SIZE}G\nMemory: ${MEMORY}MB\nStorage: $STORAGE\nNetwork: $NET_TYPE\nStatic IP: $IP_ADDR\nGateway: ${GATEWAY:-Auto}\nDNS: ${DNS_SERVERS:-Auto}\n\nProceed?" 20 60 178 | if [ $? -ne 0 ]; then 179 | echo "Code Red. Abort. Abort. Abort." 180 | exit 1 181 | fi 182 | echo "Forging LXC Container..." 183 | pct create $INSTANCE_ID local:vztmpl/$TEMPLATE -hostname $INSTANCE_NAME -storage $STORAGE -rootfs ${STORAGE}:${DISK_SIZE} -cores $CPU_CORES -memory $MEMORY -password $PASSWORD -net0 "name=eth0,bridge=vmbr0,ip=$IP_ADDR$( [[ -n "$GATEWAY" ]] && echo ",gw=$GATEWAY")" -features keyctl=$LXC_KEYCTL -unprivileged $LXC_PRIV 184 | # Apply DNS settings if set 185 | if [[ -n "$DNS_SERVERS" ]]; then 186 | echo "Setting custom DNS servers..." 187 | echo "nameserver $DNS_SERVERS" > /etc/pve/lxc/${INSTANCE_ID}.conf 188 | fi 189 | pct start $INSTANCE_ID 190 | 191 | # Ask whether to fetch scripts from GitHub 192 | USE_GITHUB=$(whiptail --title "External Scripts" --yesno "Do you want to fetch additional scripts from GitHub?" 8 50 3>&1 1>&2 2>&3) 193 | if [[ $? -eq 0 ]]; then 194 | # Ask for GitHub script URLs 195 | GITHUB_URLS=$(whiptail --inputbox "Enter GitHub script URLs (space-separated):" 10 60 --title "GitHub Script Fetch" 3>&1 1>&2 2>&3) 196 | EXTERNAL_SCRIPTS_DIR="/root/lxc-scripts" 197 | 198 | # Create the directory if it doesn't exist 199 | mkdir -p "$EXTERNAL_SCRIPTS_DIR" 200 | 201 | # Download scripts from GitHub 202 | for url in $GITHUB_URLS; do 203 | script_name=$(basename "$url") 204 | script_path="$EXTERNAL_SCRIPTS_DIR/$script_name" 205 | 206 | # Download and make the script executable 207 | wget -q "$url" -O "$script_path" 208 | chmod +x "$script_path" 209 | done 210 | fi 211 | 212 | # Run scripts on Proxmox (not inside LXC) 213 | if [ -d "$EXTERNAL_SCRIPTS_DIR" ] && [ "$(ls -A "$EXTERNAL_SCRIPTS_DIR"/*.sh 2>/dev/null)" ]; then 214 | for script in "$EXTERNAL_SCRIPTS_DIR"/*.sh; do 215 | echo "Running $(basename "$script") on Proxmox..." 216 | bash "$script" "$INSTANCE_ID" 217 | done 218 | 219 | # Optional: Clean up scripts after execution 220 | rm -rf "$EXTERNAL_SCRIPTS_DIR" 221 | echo "Removed downloaded scripts." 222 | else 223 | echo "No scripts found in $EXTERNAL_SCRIPTS_DIR. Skipping execution." 224 | fi 225 | whiptail --title "LXC Created" --msgbox "LXC Container $INSTANCE_ID has been created and started!" 8 50 226 | fi 227 | exit 0 228 | -------------------------------------------------------------------------------- /proxmox/ultra_scripts/temp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Description: Proxmox LXC or VM Creation Script with Fixes 3 | # Version: 0.2 4 | # Created by: Clark Industries IO 5 | 6 | # Ensure whiptail is installed 7 | if ! command -v whiptail &> /dev/null; then 8 | echo "Whiptail is required but not installed. Install it using: sudo apt-get install whiptail" 9 | exit 1 10 | fi 11 | 12 | # Choose instance type 13 | CHOSEN_TYPE=$(whiptail --title "Choose VM or LXC" --menu "Select the type of instance to create:" 15 50 2 \ 14 | "VM" "Create a Virtual Machine" \ 15 | "LXC" "Create a Linux Container" 3>&1 1>&2 2>&3) 16 | 17 | if [[ $? -ne 0 ]]; then 18 | whiptail --title "Operation Cancelled" --msgbox "Instance creation cancelled." 8 50 19 | exit 1 20 | fi 21 | 22 | # Function to find next available LXC/VM ID 23 | get_next_id() { 24 | local START_ID=101 25 | local NEXT_ID=$START_ID 26 | while pvesh get /cluster/resources --type vm | jq -r '.[].vmid' | grep -q "^$NEXT_ID$"; do 27 | ((NEXT_ID++)) 28 | done 29 | echo "$NEXT_ID" 30 | } 31 | 32 | # Get available instance ID 33 | AUTO_ID=$(get_next_id) 34 | INSTANCE_ID=$(whiptail --inputbox "Enter Instance ID (default: $AUTO_ID):" 8 50 "$AUTO_ID" --title "$CHOSEN_TYPE Configuration" 3>&1 1>&2 2>&3) 35 | if [[ $? -ne 0 ]]; then exit 1; fi 36 | 37 | INSTANCE_NAME=$(whiptail --inputbox "Enter Hostname:" 8 50 "${CHOSEN_TYPE,,}-$INSTANCE_ID" --title "$CHOSEN_TYPE Configuration" 3>&1 1>&2 2>&3) 38 | if [[ $? -ne 0 ]]; then exit 1; fi 39 | 40 | DISK_SIZE=$(whiptail --inputbox "Enter Disk Size (GB):" 8 50 10 --title "$CHOSEN_TYPE Configuration" 3>&1 1>&2 2>&3) 41 | if [[ $? -ne 0 ]]; then exit 1; fi 42 | 43 | MEMORY=$(whiptail --inputbox "Enter Memory Size (MB):" 8 50 2048 --title "$CHOSEN_TYPE Configuration" 3>&1 1>&2 2>&3) 44 | if [[ $? -ne 0 ]]; then exit 1; fi 45 | 46 | # Select Storage 47 | STORAGE_OPTIONS=$(pvesm status | awk 'NR>1 {print $1}') 48 | DEFAULT_STORAGE=$(echo "$STORAGE_OPTIONS" | awk '{print $1}') 49 | STORAGE=$(whiptail --menu "Select Storage:" 15 50 5 $(for s in $STORAGE_OPTIONS; do echo "$s [X]"; done) --default-item "$DEFAULT_STORAGE" 3>&1 1>&2 2>&3) 50 | if [[ $? -ne 0 ]]; then exit 1; fi 51 | 52 | # Network Configuration 53 | NETWORK_TYPE=$(whiptail --menu "Choose Network Type:" 15 50 2 \ 54 | "DHCP" "Automatically assign IP address" \ 55 | "Static" "Manually configure IP settings" 3>&1 1>&2 2>&3) 56 | 57 | if [[ "$NETWORK_TYPE" == "Static" ]]; then 58 | IP_ADDRESS=$(whiptail --inputbox "Enter Static IP (e.g., 192.168.1.100/24):" 8 50 --title "Network Configuration" 3>&1 1>&2 2>&3) 59 | GATEWAY=$(whiptail --inputbox "Enter Gateway (e.g., 192.168.1.1):" 8 50 --title "Network Configuration" 3>&1 1>&2 2>&3) 60 | DNS=$(whiptail --inputbox "Enter DNS Server (e.g., 8.8.8.8):" 8 50 --title "Network Configuration" 3>&1 1>&2 2>&3) 61 | NET_CONFIG="ip=$IP_ADDRESS,gw=$GATEWAY" 62 | else 63 | NET_CONFIG="ip=dhcp" 64 | fi 65 | 66 | # Handle VM Creation 67 | if [[ "$CHOSEN_TYPE" == "VM" ]]; then 68 | ISO_IMAGES=$(ls /var/lib/vz/template/iso | xargs) 69 | DEFAULT_ISO=$(echo "$ISO_IMAGES" | awk '{print $1}') 70 | ISO=$(whiptail --menu "Select ISO Image:" 15 60 5 $(for i in $ISO_IMAGES; do echo "$i [X]"; done) --default-item "$DEFAULT_ISO" 3>&1 1>&2 2>&3) 71 | if [[ $? -ne 0 ]]; then exit 1; fi 72 | 73 | qm create $INSTANCE_ID --name $INSTANCE_NAME --memory $MEMORY --net0 virtio,bridge=vmbr0,$NET_CONFIG \ 74 | --ostype l26 --cdrom local:iso/$ISO --scsihw virtio-scsi-pci --boot c --agent 1 \ 75 | --sockets 1 --cores 2 --cpu host --scsi0 $STORAGE:$DISK_SIZE --ide2 $STORAGE:cloudinit 76 | qm start $INSTANCE_ID 77 | whiptail --title "VM Created" --msgbox "VM ID $INSTANCE_ID has been created and started!" 8 50 78 | fi 79 | 80 | # Handle LXC Creation 81 | if [[ "$CHOSEN_TYPE" == "LXC" ]]; then 82 | pveam update > /dev/null 83 | DISTRO=$(whiptail --menu "Choose LXC Base OS:" 15 50 2 "Debian" "Use a Debian template" "Ubuntu" "Use an Ubuntu template" 3>&1 1>&2 2>&3) 84 | TEMPLATE_LIST=$(pveam available | grep -i "$DISTRO" | awk '{print $2}') 85 | TEMPLATE=$(whiptail --menu "Select a $DISTRO template:" 15 60 6 $(for t in $TEMPLATE_LIST; do echo "$t [X]"; done) 3>&1 1>&2 2>&3) 86 | 87 | PRIVILEGED=$(whiptail --yesno "Enable Privileged Mode? Most LXCs are unprivileged." 12 50 --title "LXC Privileged Mode" 3>&1 1>&2 2>&3) 88 | [[ $? -eq 0 ]] && LXC_PRIV="1" || LXC_PRIV="0" 89 | [[ "$LXC_PRIV" == "0" ]] && LXC_KEYCTL="on" || LXC_KEYCTL="off" 90 | 91 | while true; do 92 | PASSWORD=$(whiptail --passwordbox "Enter Root Password:" 8 50 --title "LXC Configuration" 3>&1 1>&2 2>&3) 93 | CONFIRM_PASSWORD=$(whiptail --passwordbox "Confirm Root Password:" 8 50 --title "LXC Configuration" 3>&1 1>&2 2>&3) 94 | if [[ "$PASSWORD" == "$CONFIRM_PASSWORD" ]]; then 95 | break 96 | else 97 | whiptail --title "Error" --msgbox "Passwords do not match. Please try again." 8 50 98 | fi 99 | done 100 | 101 | pct create $INSTANCE_ID local:vztmpl/$TEMPLATE -hostname $INSTANCE_NAME -storage $STORAGE -rootfs ${STORAGE}:${DISK_SIZE} -memory $MEMORY -password $PASSWORD -net0 name=eth0,bridge=vmbr0,$NET_CONFIG -features keyctl=$LXC_KEYCTL -unprivileged $LXC_PRIV 102 | pct start $INSTANCE_ID 103 | whiptail --title "LXC Created" --msgbox "LXC Container $INSTANCE_ID has been created and started!" 8 50 104 | fi 105 | exit 0 106 | -------------------------------------------------------------------------------- /proxmox/ultra_scripts/vm_lxc_install.sh: -------------------------------------------------------------------------------- 1 | # !/bin/bash 2 | # Description: Proxmox LXC or VM Creation Script with git pull 3 | # Tested: Proxmox VE 8.0+ (Bookworm) 4 | # Version: 0.1 5 | # Created by: Clark Industries IO 6 | 7 | # Check if whiptail is installed 8 | if ! command -v whiptail &> /dev/null; then 9 | echo "Whiptail is required but not installed. Install it using: sudo apt-get install whiptail" 10 | exit 1 11 | fi 12 | 13 | # Prompt user to choose between VM or LXC 14 | CHOSEN_TYPE=$(whiptail --title "Choose VM or LXC" --menu "Select the type of instance to create:" 15 50 2 \ 15 | "VM" "Create a Virtual Machine" \ 16 | "LXC" "Create a Linux Container" 3>&1 1>&2 2>&3) 17 | 18 | if [[ $? -ne 0 ]]; then 19 | whiptail --title "Operation Cancelled" --msgbox "Instance creation cancelled." 8 50 20 | exit 1 21 | fi 22 | 23 | # Get the next available ID 24 | AUTO_ID=$(pvesh get /cluster/nextid) 25 | # Get common settings 26 | INSTANCE_ID=$(whiptail --inputbox "Enter Instance ID (default: $AUTO_ID):" 8 50 "$AUTO_ID" --title "$CHOSEN_TYPE Configuration" 3>&1 1>&2 2>&3) 27 | if [[ $? -ne 0 ]]; then exit 1; fi 28 | 29 | INSTANCE_NAME=$(whiptail --inputbox "Enter Hostname:" 8 50 "${CHOSEN_TYPE,,}-$INSTANCE_ID" --title "$CHOSEN_TYPE Configuration" 3>&1 1>&2 2>&3) 30 | if [[ $? -ne 0 ]]; then exit 1; fi 31 | 32 | DISK_SIZE=$(whiptail --inputbox "Enter Disk Size (in GB):" 8 50 10 --title "$CHOSEN_TYPE Configuration" 3>&1 1>&2 2>&3) 33 | if [[ $? -ne 0 ]]; then exit 1; fi 34 | 35 | MEMORY=$(whiptail --inputbox "Enter Memory Size (in MB):" 8 50 2048 --title "$CHOSEN_TYPE Configuration" 3>&1 1>&2 2>&3) 36 | if [[ $? -ne 0 ]]; then exit 1; fi 37 | 38 | # Get available storage from Proxmox 39 | STORAGE_OPTIONS=$(pvesm status | awk 'NR>1 {print $1}' | xargs) 40 | DEFAULT_STORAGE=$(echo "$STORAGE_OPTIONS" | awk '{print $1}') 41 | 42 | STORAGE=$(whiptail --menu "Select Storage:" 15 50 5 $(for s in $STORAGE_OPTIONS; do echo "$s [X]"; done) --default-item "$DEFAULT_STORAGE" 3>&1 1>&2 2>&3) 43 | if [[ $? -ne 0 ]]; then exit 1; fi 44 | 45 | # Convert storage options into a format suitable for whiptail menu 46 | STORAGE_SELECTION="" 47 | for s in $STORAGE_OPTIONS; do 48 | STORAGE_SELECTION+="$s Storage " # Correctly format without "off" 49 | done 50 | 51 | # Network Configuration 52 | NETWORK_TYPE=$(whiptail --menu "Choose Network Type:" 15 50 2 \ 53 | "DHCP" "Automatically assign IP address" \ 54 | "Static" "Manually configure IP settings" 3>&1 1>&2 2>&3) 55 | 56 | if [[ "$NETWORK_TYPE" == "Static" ]]; then 57 | IP_ADDRESS=$(whiptail --inputbox "Enter Static IP (e.g., 192.168.1.100/24):" 8 50 --title "Network Configuration" 3>&1 1>&2 2>&3) 58 | GATEWAY=$(whiptail --inputbox "Enter Gateway (e.g., 192.168.1.1):" 8 50 --title "Network Configuration" 3>&1 1>&2 2>&3) 59 | DNS=$(whiptail --inputbox "Enter DNS Server (e.g., 8.8.8.8):" 8 50 --title "Network Configuration" 3>&1 1>&2 2>&3) 60 | NET_CONFIG="ip=$IP_ADDRESS,gw=$GATEWAY" 61 | else 62 | NET_CONFIG="ip=dhcp" 63 | fi 64 | 65 | # VM Creation 66 | if [[ "$CHOSEN_TYPE" == "VM" ]]; then 67 | ISO_IMAGES=$(ls /var/lib/vz/template/iso | xargs) 68 | DEFAULT_ISO=$(echo "$ISO_IMAGES" | awk '{print $1}') 69 | 70 | ISO=$(whiptail --menu "Select ISO Image:" 15 60 5 $(for i in $ISO_IMAGES; do echo "$i [X]"; done) --default-item "$DEFAULT_ISO" 3>&1 1>&2 2>&3) 71 | if [[ $? -ne 0 ]]; then exit 1; fi 72 | 73 | whiptail --title "Creating VM" --msgbox "Creating VM ID $INSTANCE_ID..." 8 50 74 | qm create $INSTANCE_ID --name $INSTANCE_NAME --memory $MEMORY --net0 virtio,bridge=vmbr0,$NET_CONFIG \ 75 | --ostype l26 --cdrom local:iso/$ISO --scsihw virtio-scsi-pci --boot c --agent 1 \ 76 | --sockets 1 --cores 2 --cpu host --scsi0 $STORAGE:$DISK_SIZE --ide2 $STORAGE:cloudinit 77 | 78 | qm start $INSTANCE_ID 79 | whiptail --title "VM Created" --msgbox "VM ID $INSTANCE_ID has been created and started!" 8 50 80 | fi 81 | 82 | #LXC Creation 83 | if [[ "$CHOSEN_TYPE" == "LXC" ]]; then 84 | 85 | # Ensure template list is updated 86 | pveam update > /dev/null 87 | 88 | # Choose between Ubuntu and Debian 89 | DISTRO=$(whiptail --title "Choose LXC Base OS" --menu "Select the base OS for the LXC:" 15 50 2 \ 90 | "Debian" "Use a Debian template" \ 91 | "Ubuntu" "Use an Ubuntu template" 3>&1 1>&2 2>&3) 92 | 93 | if [[ $? -ne 0 ]]; then exit 1; fi 94 | 95 | # Get available templates based on selection 96 | TEMPLATE_LIST=$(pveam available | grep -i "$DISTRO" | awk '{print $2}') 97 | 98 | if [ -z "$TEMPLATE_LIST" ]; then 99 | whiptail --title "Error" --msgbox "No $DISTRO templates found. Run 'pveam update' to refresh." 8 50 100 | exit 1 101 | fi 102 | 103 | # User selection of template 104 | TEMPLATE=$(whiptail --title "Choose LXC Template" --menu "Select a $DISTRO template:" 15 60 6 \ 105 | $(for t in $TEMPLATE_LIST; do echo "$t [X]"; done) 3>&1 1>&2 2>&3) 106 | 107 | if [[ $? -ne 0 ]]; then exit 1; fi 108 | 109 | # Format the options for whiptail 110 | TEMPLATE_OPTIONS=() 111 | for template in $TEMPLATE_LIST; do 112 | TEMPLATE_OPTIONS+=("$template" "$template") 113 | done 114 | 115 | # Privileged or Unprivileged LXC 116 | PRIVILEGED=$(whiptail --yesno "Do you want to create a Privileged container? \n\n⚠️ WARNING: Most LXCs are unprivileged for security.\nProceed with caution if enabling privileged mode." 12 50 --title "LXC Privileged Mode" 3>&1 1>&2 2>&3) 117 | if [[ $? -eq 0 ]]; then 118 | LXC_PRIV="1" 119 | LXC_KEYCTL="off" 120 | else 121 | LXC_PRIV="0" 122 | LXC_KEYCTL="on" 123 | fi 124 | 125 | # Password for root user 126 | PASSWORD=$(whiptail --passwordbox "Enter Root Password:" 8 50 --title "LXC Configuration" 3>&1 1>&2 2>&3) 127 | PASSWORD_CONFIRM=$(whiptail --passwordbox "Confirm Root Password:" 8 50 --title "LXC Configuration" 3>&1 1>&2 2>&3) 128 | 129 | if [[ "$PASSWORD" != "$PASSWORD_CONFIRM" ]]; then 130 | whiptail --title "Error" --msgbox "Passwords do not match! Please restart." 8 50 131 | exit 1 132 | fi 133 | 134 | # Confirm settings 135 | whiptail --title "Confirm Settings" --yesno "Container ID: $INSTANCE_ID\nHostname: $INSTANCE_NAME\nDebian Version: $SELECTED_TEMPLATE\nDisk Size: ${DISK_SIZE}G\nMemory: ${MEMORY}MB\nStorage: $STORAGE\nNetwork: $NET_TYPE\nStatic IP: $IP_ADDR\nGateway: $GATEWAY\nDNS: ${DNS_SERVERS:-Auto}\n\nProceed?" 20 60 136 | if [ $? -ne 0 ]; then 137 | echo "Aborted." 138 | exit 1 139 | fi 140 | 141 | # Check if template exists locally, download if missing 142 | if ! pveam list local | grep -q "$TEMPLATE"; then 143 | echo "Template $TEMPLATE not found locally. Downloading..." 144 | pveam download local $TEMPLATE 145 | if [[ $? -ne 0 ]]; then 146 | echo "Failed to download $TEMPLATE. Exiting." 147 | exit 1 148 | fi 149 | fi 150 | 151 | # Create LXC container 152 | echo "Creating LXC container..." 153 | pct create $INSTANCE_ID local:vztmpl/$TEMPLATE \ 154 | -hostname $INSTANCE_NAME \ 155 | -storage $STORAGE \ 156 | -rootfs ${STORAGE}:${DISK_SIZE} \ 157 | -memory $MEMORY \ 158 | -password $PASSWORD \ 159 | -net0 name=eth0,bridge=vmbr0,$NET_CONFIG \ 160 | -features keyctl=$LXC_KEYCTL \ 161 | -unprivileged $LXC_PRIV 162 | 163 | echo "Starting LXC container..." 164 | pct start $INSTANCE_ID 165 | 166 | # Ask whether to fetch scripts from GitHub 167 | USE_GITHUB=$(whiptail --title "External Scripts" --yesno "Do you want to fetch installation scripts from GitHub?" 8 50 3>&1 1>&2 2>&3) 168 | if [[ $? -eq 0 ]]; then 169 | 170 | # Ask for GitHub script URLs 171 | GITHUB_URLS=$(whiptail --inputbox "Enter GitHub script URLs (space-separated):" 10 60 --title "GitHub Script Fetch" 3>&1 1>&2 2>&3) 172 | EXTERNAL_SCRIPTS_DIR="/root/lxc-scripts" 173 | 174 | # Create the directory if it doesn't exist 175 | mkdir -p "$EXTERNAL_SCRIPTS_DIR" 176 | 177 | # Download scripts from GitHub 178 | for url in $GITHUB_URLS; do 179 | script_name=$(basename "$url") 180 | script_path="$EXTERNAL_SCRIPTS_DIR/$script_name" 181 | 182 | # Download and make the script executable 183 | wget -q "$url" -O "$script_path" 184 | chmod +x "$script_path" 185 | done 186 | fi 187 | 188 | # Run scripts on Proxmox (not inside LXC) 189 | if [ -d "$EXTERNAL_SCRIPTS_DIR" ] && [ "$(ls -A "$EXTERNAL_SCRIPTS_DIR"/*.sh 2>/dev/null)" ]; then 190 | for script in "$EXTERNAL_SCRIPTS_DIR"/*.sh; do 191 | echo "Running $(basename "$script") on Proxmox..." 192 | bash "$script" "$INSTANCE_ID" 193 | done 194 | 195 | # Optional: Clean up scripts after execution 196 | if [ "$(ls -A "$EXTERNAL_SCRIPTS_DIR"/*.sh 2>/dev/null)" ]; then 197 | rm -rf "$EXTERNAL_SCRIPTS_DIR" 198 | fi 199 | echo "Removed downloaded scripts." 200 | 201 | # Remove the installer script itself 202 | rm -- "$0" 203 | 204 | echo "LXC Container $INSTANCE_ID setup complete!" 205 | whiptail --title "Setup Complete" --msgbox "LXC Container $INSTANCE_ID setup is complete!" 8 50 206 | fi 207 | exit 0 --------------------------------------------------------------------------------